Passed
Pull Request — dev (#855)
by
unknown
02:03
created

data.datasets.plotdatascn.set_epsg_network()   A

Complexity

Conditions 1

Size

Total Lines 19
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

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