#!/usr/bin/env python
# coding: utf-8
# # Plotting traces (collections)
# This Tutorial explains how to customize network plots in pandapower using plotly. Each pandapower network element can be translated into a plotly trace with all corresponding properties.
# In[1]:
import pandapower as pp
import pandapower.networks as nw
import pandapower.plotting.plotly as pplotly
from pandas import Series
import numpy as np
# We created a network along with geodata in the buses.
# In[2]:
net = pp.create_empty_network()
x=np.array([0,-2,2,-3,-2,2])
y=np.array([4,3,3,-3,-2,-2])
for i in range(6):
if i < 3:
v = 110
elif i == 3:
v = 20
else:
v=10
pp.create_bus(net, vn_kv=v,geodata=(x[i], y[i]))
pp.create_line(net, 0, 1, 5, "149-AL1/24-ST1A 110.0",geodata=None,name='l1')
pp.create_line(net, 0, 2, 5, "149-AL1/24-ST1A 110.0",geodata=None,name='l2')
pp.create_transformer3w(net, 1, 3, 4, "63/25/38 MVA 110/20/10 kV", name='tr1')
pp.create_transformer(net, 2, 5, "0.25 MVA 20/0.4 kV", name='tr2')
pp.create_ext_grid(net, 0)
pp.create_load(net, 4, p_mw=20., q_mvar=10., name='load1')
pp.create_load(net, 5, p_mw=20., q_mvar=10., name='load1')
# If you want to have full control over the layout of your plot, you can individually create and plot collections with the pandapower plotting module.
# In[3]:
lc = pplotly.create_line_trace(net,net.line.index, color='black',infofunc=net.line.name)
bc = pplotly.create_bus_trace(net, net.bus.index, size=10, color="orange",infofunc=net.bus.vn_kv)
tc3 = pplotly.create_trafo_trace(net, net.trafo3w.index,trafotype='3W', color='green', infofunc=net.trafo3w.name,trace_name='trafo3ws', cmin=None, cmax=None, cmap_vals=None,use_line_geo=None)
tc = pplotly.create_trafo_trace(net, net.trafo.index, trafotype='2W',color='blue', infofunc=net.trafo.name,trace_name='trafos', cmin=None, cmax=None, cmap_vals=None,use_line_geo=None)
_ = pplotly.draw_traces(bc+lc+tc+tc3, figsize=1, aspectratio=(8,4));
# In[4]:
net = nw.mv_oberrhein()
lc = pplotly.create_line_trace(net,net.line.index, color='black')
bc = pplotly.create_bus_trace(net, net.bus.index, size=10, color="orange",
infofunc=Series(index=net.bus.index,
data=net.bus.name + '
' + net.bus.vn_kv.astype(str) + ' kV'))
pplotly.draw_traces(bc + lc, figsize=1, aspectratio=(8,6));
# Order of plotting traces is as ordered in the `draw_traces` function. So, in order to plot buses in front of lines first lines and then buses need to be set in the input traces list:
# In[41]:
pplotly.draw_traces(lc + bc , figsize=1, aspectratio=(8,6));
# ## Highlighting
# Specific lines or buses can be highlighted by creating extra line collections in different colors.
#
# In this example, we plot lines that are longer than 2 km green and buses with a voltage below 0.98 p.u. red.
#
# First, we create a line collection for all lines in grey and a line collection for only the long lines in green:
# In[42]:
long_lines = net.line[net.line.length_km > 2.].index
lc = pplotly.create_line_trace(net, net.line.index, color="grey")
lcl = pplotly.create_line_trace(net, long_lines, color="green", width=2,
infofunc=Series(index=net.line.index,
data=net.line.name[long_lines] + '
' + net.line.length_km[long_lines].astype(str) + ' km'))
low_voltage_buses = net.res_bus[net.res_bus.vm_pu < 0.98].index
bc = pplotly.create_bus_trace(net, net.bus.index, size=10, color="blue")
bch = pplotly.create_bus_trace(net, low_voltage_buses, size=10, color="red")
pplotly.draw_traces(bc + bch + lc + lcl );
# ## Highlighting with the Topology Package
# Colors palette for plotly can be obtained using function `plotting.plotly.get_plotly_color_palette(n)` where argument `n` defines number of colors that will be returned in a list.
# In[43]:
from pandapower.plotting.plotly import get_plotly_color_palette
net = nw.mv_oberrhein()
mg = pp.topology.create_nxgraph(net, nogobuses=set(net.trafo.lv_bus.values) | set(net.trafo.hv_bus.values))
collections = []
ai = 0
islands = list(pp.topology.connected_components(mg)) # getting connected components of a graph
colors = get_plotly_color_palette(len(islands)) # getting a color for each connected component
for color, area in zip(colors, islands):
collections += pplotly.create_bus_trace(net, area, size=5, color=color, trace_name='feeder {0}'.format(ai))
ai += 1
collections += pplotly.create_line_trace(net, net.line.index, color="grey")
collections += pplotly.create_bus_trace(net, net.ext_grid.bus.values, patch_type="square", size=10,
color="yellow")
pplotly.draw_traces(collections);
# ## Collection on mapbox
# Plots on Mapbox maps are available only considering you have a Mapbox account and a Mapbox Access Token. After getting a mabox token it can be written set to pandapower as the following (where `''` needs to be replaced with provided mapbox token).
# If network geo-data are not in lat/long form, there is a function `geo_data_to_latlong` which can be used to transform entire network geodata from a specific projection to lat/long:
# In[44]:
from pandapower.plotting.plotly.mapbox_plot import set_mapbox_token
set_mapbox_token('')
net = nw.mv_oberrhein()
pplotly.geo_data_to_latlong(net, projection='epsg:31467') #transforming geodata to lat/long
lc = pplotly.create_line_trace(net, net.line.index, color='purple')
bc = pplotly.create_bus_trace(net, net.bus.index,size=10,color="orange",
infofunc=Series(index=net.bus.index,
data=net.bus.name + '
' + net.bus.vn_kv.astype(str) + ' kV'))
_ = pplotly.draw_traces(lc + bc, on_map=True, map_style='dark')
# ## Colormaps
# Colormaps plots are available for plotly by setting `cmap=True` in create functions. By default, line loading and bus voltage magnitudes will be used for coloring.
# In[45]:
net = nw.mv_oberrhein()
bt = pplotly.create_bus_trace(net, cmap=True)
lt = pplotly.create_line_trace(net, cmap=True)
pplotly.draw_traces(lt + bt, showlegend=False);
# Some customization is possible in regard to: limits, choosing a colormap, colorbar title, etc.
# In[46]:
lt = pplotly.create_line_trace(net, cmap='Blues', cmin=0, cmax=100, cbar_title = 'Line loading [%]')
pplotly.draw_traces(lt, showlegend=False);
# Alternatively, any other values can be used for colormaps, with also some customization in regard to limits, choosing a colormap, colorbar title, etc. An example with coloring according to line length:
# In[47]:
lt = pplotly.create_line_trace(net, cmap_vals=net.line.length_km, cmap=True, cbar_title = 'Line length [km]')
pplotly.draw_traces(lt, showlegend=False);
# ## Customized hover-info
# Information that pop-ups when a bus or a line is pointed with mouse-cursor is called hover-info. By default, it is set to bus/line name, but it can be customized by setting a list of strings to `infofunc` argument. A newline is defined using `
`. See a representative example hereafter (try getting hoverinfo by pointing a cursor above each bus):
# In[48]:
bc = pplotly.create_bus_trace(net, [1,2,3,4,5], size=15,
infofunc=Series(index=net.bus.index, data=net.bus.name + '
' +
net.bus.vn_kv.astype(str) + ' kV' + '
' +
'this is one of the 5 buses...'))
pplotly.draw_traces(bc);
# ## Weighted Marker Traces
# A trace with markers of value-dependent size can be created by the `create_weighted_marker_trace` function. Like other traces, this trace can be passed to `draw_traces` directly, or it can be passed as "additional trace" to `simple_plotly`. By default, the latter will also add a reference marker to indicate the value for one size.
# In[49]:
net.sgen.scaling = 1
marker_trace = pplotly.create_weighted_marker_trace(net, "sgen", column_to_plot="p_mw", marker_scaling=200, color="green", patch_type="circle-open")
_ = pplotly.simple_plotly(net, bus_size=0.25, additional_traces=[marker_trace])
# More tutorials about interactive plots using plotly:
# * [built-in interactive plots](https://github.com/e2nIEE/pandapower/blob/develop/tutorials/plotly_built-in.ipynb)
# * [interactive plots on maps](https://github.com/e2nIEE/pandapower/blob/develop/tutorials/plotly_maps.ipynb)