Passed
Pull Request — dev (#855)
by
unknown
01:42
created

data.datasets.plotdatascn.plot_osm()   A

Complexity

Conditions 1

Size

Total Lines 40
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 13
dl 0
loc 40
rs 9.75
c 0
b 0
f 0
cc 1
nop 4
1
#!/usr/bin/env python3
2
# -*- coding: utf-8 -*-
3
# File description
4
"""
5
Created on Tue May 24 14:42:05 2022
6
Plotdatascn.py defines functions to plot to provide a better context of the different parameters part of
7
scenarios eGon2035 and eGon100RE .
8
@author: Alonso
9
10
""" 
11
import logging
12
import os
13
from matplotlib import pyplot as plt
14
import matplotlib as mpl
15
import pandas as pd
16
from math import sqrt, log10
17
from pyproj import Proj, transform
18
from egon.data import db
19
import egon.data.config
20
import geopandas as gpd
21
import tilemapbase
22
from math import sqrt, log10
23
from pyproj import Proj, transform
24
from matplotlib_scalebar.scalebar import ScaleBar
25
26
27
logger = logging.getLogger(__name__)
28
29
if 'READTHEDOCS' not in os.environ:
30
    from geoalchemy2.shape import to_shape
31
32
__copyright__ = ("Flensburg University of Applied Sciences, "
33
                 "Europa-Universität Flensburg, "
34
                 "Centre for Sustainable Energy Systems, "
35
                 "DLR-Institute for Networked Energy Systems")
36
__license__ = ""
37
__author__ = ""
38
39
  
40
def set_epsg_network(network):
41
    """
42
    Change EPSG from 4326 to 3857. Needed when using osm-background.
43
44
    Parameters
45
    ----------
46
    network : PyPSA network container
47
48
    Returns
49
    -------
50
    """
51
52
    inProj = Proj(init='epsg:4326')
53
    outProj = Proj(init='epsg:3857')
54
    x1, y1 = network.buses.x.values, network.buses.y.values
55
    x2, y2 = transform(inProj, outProj, x1, y1)
56
    network.buses.x, network.buses.y = x2, y2
57
    network.epsg = 3857
58
    set_epsg_network.counter = set_epsg_network.counter + 1
59
    
60
def plot_osm(x, y, zoom, alpha=0.4):
61
    """
62
    Plots openstreetmap as background of network-plots
63
64
    Parameters
65
    ----------
66
    x : array of two floats
67
        Define x-axis boundaries (lat) of osm plot
68
    y : array of two floats
69
        Define y-axis boundaries (long) of osm plot
70
    zoom : int
71
        Define zoom of osm, higher values for higher resolution
72
    alpha : float
73
        Sets osm-visibility, increase value if osm covers network-plot
74
    osm : bool or dict, e.g. {'x': [1,20], 'y': [47, 56], 'zoom' : 6}
75
        If not False, osm is set as background
76
        with the following settings as dict:
77
                'x': array of two floats, x axis boundaries (lat)
78
                'y': array of two floats, y axis boundaries (long)
79
                'zoom' : resolution of osm. The default is False.
80
81
    Returns
82
    -------
83
    """
84
85
    tilemapbase.init(create=True)
86
87
    extent = tilemapbase.Extent.from_lonlat(x[0], x[1], y[0], y[1])
88
    extent = extent.to_aspect(1.0)
89
    extent = extent.to_project_3857()
90
91
    fig, ax = plt.subplots(1,1)
92
    ax.set_zorder(1)
93
    ax.add_artist(ScaleBar(1))
94
    plt.axis('off')
95
    plotter = tilemapbase.Plotter(extent, tilemapbase.tiles.build_OSM(),
96
                                  zoom=zoom)
97
    plotter.plot(ax, alpha=alpha)
98
    #ax.plot(x, y, "ro-")
99
    return fig, ax
100
101
def plot_generation(
102
              carrier,scenario, osm = False
103
            ):
104
   """
105
    Plots color maps according to the capacity of different generators
106
    of the two existing scenarios (eGon2035 and eGon100RE)
107
    
108
109
    Parameters
110
    ----------
111
    carrier : generators
112
    The list of generators: biomass, central_biomass_CHP, central_biomass_CHP_heat,
113
    industrial_biomass_CHP, solar, solar_rooftop, wind_offshore, wind_onshore. 
114
      
115
    scenario: eGon2035, eGon100RE
116
        
117
        
118
   """
119
    
120
121
   con = db.engine()
122
   #imports buses of Germany
123
   SQLBus = "SELECT bus_id, country FROM grid.egon_etrago_bus WHERE country='DE'" 
124
   busDE = pd.read_sql(SQLBus,con) 
125
   busDE = busDE.rename({'bus_id': 'bus'},axis=1) 
126
   #Imports grid districs
127
   sql = "SELECT bus_id, geom FROM grid.egon_mv_grid_district" 
128
   distr = gpd.GeoDataFrame.from_postgis(sql, con)
129
   distr = distr.rename({'bus_id': 'bus'},axis=1)
130
   distr = distr.set_index("bus")
131
   #merges grid districts with buses 
132
   distr = pd.merge(busDE, distr, on='bus') 
133
   #Imports generator
134
   sqlCarrier = "SELECT carrier, p_nom, bus FROM grid.egon_etrago_generator" 
135
   sqlCarrier = "SELECT * FROM grid.egon_etrago_generator"
136
   Carriers = pd.read_sql(sqlCarrier,con)
137
   Carriers = Carriers.loc[Carriers['scn_name'] == scenario]
138
   Carriers = Carriers.set_index("bus")
139
140
141
   CarrierGen = Carriers.loc[Carriers['carrier'] == carrier]
142
   #merges districts with generators 
143
   Merge = pd.merge(CarrierGen, distr, on ='bus', how="outer")  
144
145
    
146
   Merge.loc[Merge ['carrier'] != carrier, "p_nom" ] = 0
147
   Merge.loc[Merge ['country'] != "DE", "p_nom" ] = 0
148
149
   gdf = gpd.GeoDataFrame(Merge , geometry='geom')
150
   pnom=gdf['p_nom']  #
151
   #0.95 quantile is used to filter values that are too high and make noise in the plots.
152
   max_pnom=pnom.quantile(0.95) 
153
   gdf = gdf.to_crs(epsg=3857)
154
155
   
156
   # Plot osm map in background
157
   if osm != False:
158
       #if network.srid == 4326:
159
           #set_epsg_network(network)
160
       fig, ax = plot_osm(osm['x'], osm['y'], osm['zoom'])
161
162
   else:
163
       fig, ax = plt.subplots(1, 1)
164
   
165
   
166
   
167
   ax.set_axis_off();
168
   plt.title(f" {carrier} installed capacity in MW , {scenario}")
169
   cmap = mpl.cm.coolwarm
170
   
171
  
172
   norm = mpl.colors.Normalize(vmin=0, vmax=max_pnom)
173
   gdf.plot(column='p_nom', ax=ax, legend=False,  legend_kwds={'label': "p_nom(MW)",
174
175
                       'orientation': "vertical"}, cmap=cmap, norm=norm, edgecolor='black', linewidth=0.1,zorder=2)
176
   scatter = ax.collections[0]
177
   cbar=plt.colorbar(scatter, ax=ax, extend='max')
178
   cbar.set_label('p_nom(MW)', rotation=90)
179
   return 0
180
      
181
182
   
183
   
184
   
185