Skip to content

Commit

Permalink
Merge pull request #2469 from KS-HTK/issues/1785-related
Browse files Browse the repository at this point in the history
Deprecated projection keyword in simple_plotly
  • Loading branch information
vogt31337 authored Dec 19, 2024
2 parents 8e94af3 + ab151f1 commit a99f884
Show file tree
Hide file tree
Showing 3 changed files with 161 additions and 119 deletions.
53 changes: 12 additions & 41 deletions pandapower/plotting/plotly/mapbox_plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@


import os

from typing_extensions import deprecated

from pandapower.plotting import geo

try:
Expand All @@ -26,20 +29,22 @@ def _on_map_test(x, y):
except ImportError:
# if geopy is not available there will be no geo-coordinates check
# therefore if geo-coordinates are not real and user sets on_map=True, an empty map will be plot!
raise ImportError('Geo-coordinates check cannot be peformed because geopy package not available \n\t--> '
'if geo-coordinates are not in lat/lon format an empty plot may appear...')
raise ImportError(
'Geo-coordinates check cannot be performed because geopy package not available \n\t--> '
'if geo-coordinates are not in lat/lon format an empty plot may appear...'
)
try:
location = geolocator.reverse("{0}, {1}".format(x, y), language='en-US')
location = geolocator.reverse(f"{x}, {y}", language='en-US')
except GeocoderTimedOut:
logger.error("Existing net geodata cannot be geo-located: possible reason: geo-data not in lat/long ->"
"try geo_data_to_latlong(net, projection) to transform geodata to lat/long!")

if location.address is None:
return False
else:
return True
if location.address is None:
return False
return True


@deprecated('geo_data_to_latlong is deprecated and will be removed shortly, use pandapower.geo.convert_crs instead')
def geo_data_to_latlong(net, projection):
"""
Transforms network's geodata (in `net.bus_geodata` and `net.line_geodata`) from specified projection to lat/long (WGS84).
Expand All @@ -55,40 +60,6 @@ def geo_data_to_latlong(net, projection):
"""
geo.convert_crs(net, epsg_in=projection.split(':')[1], epsg_out=4326)

# try:
# from pyproj import Proj, transform
# except ImportError:
# raise ImportError('Geo-coordinates check cannot be peformed because pyproj package not available \n\t--> '
# 'if geo-coordinates are not in lat/lon format an empty plot may appear...')
#
# if projection == 'epsg:4326':
# return
#
# wgs84 = Proj(init='epsg:4326') # lat/long
#
# try:
# projection = Proj(init=projection)
# except:
# logger.warning("Transformation of geodata to lat/long failed! because of:]\n"
# "Unknown projection provided "
# "(format 'epsg:<number>' required as available at http://spatialreference.org/ref/epsg/ )")
# return
#
# # transform all geodata to long/lat using set or found projection
# try:
# lon, lat = transform(projection, wgs84, net.bus_geodata.loc[:, 'x'].values, net.bus_geodata.loc[:, 'y'].values)
# net.bus_geodata.loc[:, 'x'], net.bus_geodata.loc[:, 'y'] = lon, lat
#
# if net.line_geodata.shape[0] > 0:
# for idx in net.line_geodata.index:
# line_coo = np.array(net.line_geodata.loc[idx, 'coords'])
# lon, lat = transform(projection, wgs84, line_coo[:, 0], line_coo[:, 1])
# net.line_geodata.loc[idx, 'coords'] = np.array([lon, lat]).T.tolist()
# return
# except:
# logger.warning('Transformation of geodata to lat/long failed!')
# return


def set_mapbox_token(token):
from pandapower.__init__ import pp_dir
Expand Down
223 changes: 147 additions & 76 deletions pandapower/plotting/plotly/simple_plotly.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
# and Energy System Technology (IEE), Kassel. All rights reserved.


import warnings
from typing_extensions import overload
import pandas as pd

from pandapower.plotting.generic_geodata import create_generic_coordinates
Expand Down Expand Up @@ -98,12 +100,33 @@ def get_hoverinfo(net, element, precision=3, sub_index=None):
return hoverinfo


@overload
def simple_plotly(net, respect_switches=True, use_line_geo=None, on_map=False,
*, map_style='basic', figsize=1.0, aspectratio='auto',
line_width=1.0, bus_size=10.0, ext_grid_size=20.0,
bus_color="blue", line_color='grey', trafo_color='green',
trafo3w_color='green', ext_grid_color="yellow",
filename='temp-plot.html', auto_open=True, showlegend=True,
additional_traces=None, zoomlevel=11, auto_draw_traces=True, hvdc_color='cyan'): ...


@overload
@deprecated("projection is deprecated and will be removed in future versions. geojson should always be WGS84.")
def simple_plotly(net, respect_switches=True, use_line_geo=None, on_map=False,
projection='epsg:4326', map_style='basic', figsize=1.0, aspectratio='auto',
line_width=1.0, bus_size=10.0, ext_grid_size=20.0,
bus_color="blue", line_color='grey', trafo_color='green',
trafo3w_color='green', ext_grid_color="yellow",
filename='temp-plot.html', auto_open=True, showlegend=True,
additional_traces=None, zoomlevel=11, auto_draw_traces=True, hvdc_color='cyan'): ...


def simple_plotly(net, respect_switches=True, use_line_geo=None, on_map=False,
projection=None, map_style='basic', figsize=1.0, aspectratio='auto',
line_width=1.0, bus_size=10.0, ext_grid_size=20.0,
bus_color="blue", line_color='grey', trafo_color='green',
trafo3w_color='green', ext_grid_color="yellow",
filename='temp-plot.html', auto_open=True, showlegend=True,
additional_traces=None, zoomlevel=11, auto_draw_traces=True, hvdc_color='cyan'):
"""
Plots a pandapower network as simple as possible in plotly.
Expand Down Expand Up @@ -173,40 +196,47 @@ def simple_plotly(net, respect_switches=True, use_line_geo=None, on_map=False,
OUTPUT:
**figure** (graph_objs._figure.Figure) figure object
"""
node_element = "bus"
branch_element = "line"
trans_element = "trafo"
trans3w_element = "trafo3w"
separator_element = "switch"
traces, settings = _simple_plotly_generic(net=net,
respect_separators=respect_switches,
use_branch_geodata=use_line_geo,
on_map=on_map,
projection=projection,
map_style=map_style,
figsize=figsize,
aspectratio=aspectratio,
branch_width=line_width,
node_size=bus_size,
ext_grid_size=ext_grid_size,
node_color=bus_color,
branch_color=line_color,
trafo_color=trafo_color,
trafo3w_color=trafo3w_color,
ext_grid_color=ext_grid_color,
node_element=node_element,
branch_element=branch_element,
trans_element=trans_element,
trans3w_element=trans3w_element,
separator_element=separator_element,
branch_trace_func=create_line_trace,
node_trace_func=create_bus_trace,
hoverinfo_func=get_hoverinfo,
filename=filename,
auto_open=auto_open,
showlegend=showlegend,
zoomlevel=zoomlevel,
hvdc_color=hvdc_color)
if projection is not None:
warnings.warn(
FutureWarning(
"projection is deprecated and will be removed in future versions. geojson should always be WGS84."
),
stacklevel=2
)

settings = dict(
on_map=on_map,
map_style=map_style,
figsize=figsize,
aspectratio=aspectratio,
filename=filename,
auto_open=auto_open,
showlegend=showlegend,
zoomlevel=zoomlevel
)

traces, _ = _simple_plotly_generic(
net=net,
respect_separators=respect_switches,
use_branch_geodata=use_line_geo,
branch_width=line_width,
node_size=bus_size,
ext_grid_size=ext_grid_size,
node_color=bus_color,
branch_color=line_color,
trafo_color=trafo_color,
trafo3w_color=trafo3w_color,
ext_grid_color=ext_grid_color,
node_element="bus",
branch_element="line",
trans_element="trafo",
trans3w_element="trafo3w",
branch_trace_func=create_line_trace,
node_trace_func=create_bus_trace,
hoverinfo_func=get_hoverinfo,
hvdc_color=hvdc_color,
settings=settings
)
if additional_traces:
if isinstance(additional_traces, dict):
additional_traces = [additional_traces]
Expand All @@ -225,33 +255,55 @@ def simple_plotly(net, respect_switches=True, use_line_geo=None, on_map=False,
else:
return traces, settings

def _simple_plotly_generic(net, respect_separators, use_branch_geodata, on_map, projection, map_style,
figsize, aspectratio, branch_width, node_size, ext_grid_size, node_color,
branch_color, trafo_color, trafo3w_color, ext_grid_color,

def _simple_plotly_generic(net, respect_separators, use_branch_geodata, branch_width, node_size, ext_grid_size,
node_color, branch_color, trafo_color, trafo3w_color, ext_grid_color,
node_element, branch_element, trans_element, trans3w_element,
separator_element, branch_trace_func, node_trace_func,
hoverinfo_func, filename='temp-plot.html', auto_open=True,
showlegend=True, zoomlevel=11, hvdc_color="cyan"):
settings = dict(on_map=on_map, projection=projection, map_style=map_style, figsize=figsize,
aspectratio=aspectratio, filename=filename, auto_open=auto_open,
showlegend=showlegend, zoomlevel=zoomlevel)
branch_trace_func, node_trace_func, hoverinfo_func,
hvdc_color="cyan", settings=None, **kwargs):

if 'projection' in kwargs:
warnings.warn(
FutureWarning(
"projection is deprecated and will not be used. geojson should always be WGS84."
),
stacklevel=2
)
kwargs.pop('projection')

settings_defaults = { # if no settings are provided, these are used
'on_map': kwargs.get('on_map', True),
'map_style': kwargs.get('map_style', 'basic'),
'figsize': kwargs.get('figsize', 1.),
'aspectratio': kwargs.get('aspectratio', 'auto'),
'filename': kwargs.get('filename', 'temp-plot.html'),
'auto_open': kwargs.get('auto_open', 'auto'),
'showlegend': kwargs.get('showlegend', True),
'zoomlevel': kwargs.get('zoomlevel', 11)
}

settings = settings_defaults | settings if settings else {} # add missing settings to settings dict

if len(net[node_element]["geo"].dropna()) == 0:
logger.warning("No or insufficient geodata available --> Creating artificial coordinates." +
" This may take some time...")
logger.warning(
"No or insufficient geodata available --> Creating artificial coordinates. This may take some time..."
)
create_generic_coordinates(net, respect_switches=respect_separators)
if on_map:
if settings['on_map']:
logger.warning(
"Map plots not available with artificial coordinates and will be disabled!")
on_map = False
# check if geodata are real geographical lat/lon coordinates using geopy
if on_map and projection is not None:
geo_data_to_latlong(net, projection=projection)
settings['on_map'] = False

# ----- Nodes (Buses) ------
# initializing node trace
hoverinfo = hoverinfo_func(net, element=node_element)
node_trace = node_trace_func(net, net[node_element].index, size=node_size, color=node_color,
infofunc=hoverinfo)
node_trace = node_trace_func(
net,
net[node_element].index,
size=node_size,
color=node_color,
infofunc=hoverinfo
)
# ----- branches (Lines) ------
# if node geodata is available, but no branch geodata
if use_branch_geodata is None:
Expand All @@ -261,51 +313,66 @@ def _simple_plotly_generic(net, respect_separators, use_branch_geodata, on_map,
"No or insufficient line geodata available --> only bus geodata will be used.")
use_branch_geodata = False
hoverinfo = hoverinfo_func(net, element=branch_element)
branch_traces = branch_trace_func(net, net[branch_element].index, use_branch_geodata,
respect_separators,
color=branch_color, width=branch_width,
infofunc=hoverinfo)
branch_traces = branch_trace_func(
net,
net[branch_element].index,
use_branch_geodata,
respect_separators,
color=branch_color,
width=branch_width,
infofunc=hoverinfo
)
trans_trace = []
trans_trace3w = []
ext_grid_trace = []
dc_line_trace = []
# ----- Trafos ------
if 'trafo' in net and len(net.trafo):
hoverinfo = hoverinfo_func(net, element=trans_element)
trans_trace = create_trafo_trace(net, color=trafo_color, width=branch_width * 5,
infofunc=hoverinfo,
use_line_geo=use_branch_geodata)
trans_trace = create_trafo_trace(
net,
color=trafo_color,
width=branch_width * 5,
infofunc=hoverinfo,
use_line_geo=use_branch_geodata
)
# ----- 3W Trafos ------
if 'trafo3w' in net and len(net.trafo3w):
hoverinfo = hoverinfo_func(net, element=trans3w_element)
trans_trace3w = create_trafo_trace(net, color=trafo3w_color, trafotype='3W',
width=branch_width * 5,
trace_name='3W transformers', infofunc=hoverinfo,
use_line_geo=use_branch_geodata)
trans_trace3w = create_trafo_trace(
net, color=trafo3w_color, trafotype='3W',
width=branch_width * 5,
trace_name='3W transformers',
infofunc=hoverinfo,
use_line_geo=use_branch_geodata
)
# ----- Ext grid ------
# get external grid from _create_node_trace
if 'ext_grid' in net and len(net.ext_grid):
marker_type = 'circle' if on_map else 'square' # workaround because doesn't appear on mapbox if square
marker_type = 'circle' if settings['on_map'] else 'square' # workaround because doesn't appear on mapbox if square
hoverinfo = hoverinfo_func(net, element="ext_grid")
ext_grid_trace = _create_node_trace(net, nodes=net.ext_grid[node_element], size=ext_grid_size,
patch_type=marker_type, color=ext_grid_color,
infofunc=hoverinfo, trace_name='external grid',
node_element=node_element, branch_element=branch_element)
ext_grid_trace = _create_node_trace(
net,
nodes=net.ext_grid[node_element],
size=ext_grid_size,
patch_type=marker_type,
color=ext_grid_color,
infofunc=hoverinfo,
trace_name='external grid',
node_element=node_element,
branch_element=branch_element
)
# ----- HVDC lines ------
if 'dcline' in net and len(net.dcline):
dc_line_trace = create_dcline_trace(net, color=hvdc_color)

return branch_traces + trans_trace + trans_trace3w + ext_grid_trace + node_trace + dc_line_trace,\
settings
return branch_traces + trans_trace + trans_trace3w + ext_grid_trace + node_trace + dc_line_trace, settings


if __name__ == '__main__':
from pandapower import networks as nw
from pandapower.networks import mv_oberrhein
from pandapower.plotting.plotly.traces import create_weighted_marker_trace
# simple_plotly(net)
# net = nw.example_multivoltage()
# fig = simple_plotly(net, trafo3w_color='k')

net = mv_oberrhein()
net.load.scaling, net.sgen.scaling = 1, 1
# different markers and sizemodes as examples
Expand All @@ -316,5 +383,9 @@ def _simple_plotly_generic(net, respect_separators, use_branch_geodata, on_map,
patch_type="circle-open", sizemode="diameter",
marker_scaling=100, scale_marker_size=[0.2, 0.4])

fig = simple_plotly(net, bus_size=1, aspectratio="original", additional_traces=[markers_sgen,
markers_load])
fig = simple_plotly(
net,
bus_size=1,
aspectratio="original",
additional_traces=[markers_sgen, markers_load]
)
4 changes: 2 additions & 2 deletions pandapower/plotting/plotly/traces.py
Original file line number Diff line number Diff line change
Expand Up @@ -1077,9 +1077,9 @@ def draw_traces(traces, on_map=False, map_style='basic', showlegend=True, figsiz
if on_map:
try:
on_map = _on_map_test(traces[0]['x'][0], traces[0]['y'][0])
except:
except ImportError:
logger.warning("Test if geo-data are in lat/long cannot be performed using geopy -> "
"eventual plot errors are possible.")
"plot errors are possible.")

if on_map is False:
logger.warning("Existing geodata are not real lat/lon geographical coordinates. -> "
Expand Down

0 comments on commit a99f884

Please sign in to comment.