diff --git a/pandapipes/plotting/plotly/__init__.py b/pandapipes/plotting/plotly/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/pandapipes/plotting/plotly/simple_plotly.py b/pandapipes/plotting/plotly/simple_plotly.py new file mode 100644 index 00000000..370b0e8e --- /dev/null +++ b/pandapipes/plotting/plotly/simple_plotly.py @@ -0,0 +1,168 @@ +# Copyright (c) 2022 by Fraunhofer Institute for Energy Economics +# and Energy System Technology (IEE), Kassel, and University of Kassel. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. + +import pandas as pd + +from pandapipes.plotting.plotly.traces import create_junction_trace, create_pipe_trace, \ + create_valve_trace, create_compressor_trace, create_press_control_trace +from pandapower.plotting.plotly.simple_plotly import _simple_plotly_generic, draw_traces + +try: + from pandaplan.core import pplog as logging +except ImportError: + import logging +logger = logging.getLogger(__name__) + + +def get_hoverinfo(net, element, precision=3, sub_index=None): + hover_index = net[element].index + if element == "junction": + sink_str, source_str = [], [] + if hasattr(net, "sink"): + for ln in [net.sink.loc[net.sink.junction == b, "mdot_kg_per_s"].sum() for b in + net.junction.index]: + sink_str.append("Sink: {:.3f} kg/s
".format(ln) if ln != 0. else "") + if hasattr(net, "source"): + for s in [net.source.loc[net.source.junction == b, "mdot_kg_per_s"].sum() for b in + net.junction.index]: + source_str.append("Source: {:.3f} kg/s
".format(s) if s != 0. else "") + hoverinfo = ( + "Index: " + net.junction.index.astype(str) + "
" + + "Name: " + net.junction['name'].astype(str) + "
" + + "Height: " + net.junction['height_m'].astype(str) + " m
" + + "Pressure: " + net.junction['pn_bar'].round(precision).astype(str) + " bar
" + + "Temp.: " + net.junction['tfluid_k'].round(precision).astype(str) + " K
" + # + sink_str + source_str # TODO: fix this (correct indexing) + ).tolist() + elif element == "pipe": + hoverinfo = ( + "Index: " + net.pipe.index.astype(str) + "
" + + "Name: " + net.pipe['name'].astype(str) + "
" + + "Length: " + net.pipe['length_km'].round(precision).astype(str) + " km
" + + "Diameter: " + ((net.pipe['diameter_m']).round(precision)*1e3).astype(str) + " mm" + + "
" + + "k: " + (net.pipe['k_mm']).round(precision).astype(str) + " mm
" + ).tolist() + elif element == "pump": + hoverinfo = ( + "Index: " + net.pump.index.astype(str) + "
" + + "Name: " + net.pump['name'].astype(str) + "
" + + "Std. Type: " + net.pump['std_type'] + "
" + ).tolist() + elif element == "compressor": + hoverinfo = ( + "Index: " + net.compressor.index.astype(str) + "
" + + "Name: " + net.compressor['name'].astype(str) + "
" + + "Pressure ratio: " + net.compressor['pressure_ratio'] + "
" + ).tolist() + elif element == "pressure_control": + hoverinfo = ( + "Index: " + net.pressure_control.index.astype(str) + "
" + + "Name: " + net.pressure_control['name'].astype(str) + "
" + + "controlled junction:" + net.pressure_control['controlled_junction'] + "
" + + "controlled pressure:" + net.pressure_control['controlled_p_bar'] + " bar
" + ).tolist() + elif element == "ext_grid": + hoverinfo = ( + "Index: " + net.ext_grid.index.astype(str) + "
" + + "Name: " + net.ext_grid['name'].astype(str) + "
" + + "Pressure: " + net.ext_grid['p_bar'].round(precision).astype(str) + " bar
" + + "Temp.: " + net.ext_grid['t_k'].round(precision).astype(str) + " K
" + ).tolist() + + hover_index = net.ext_grid.junction.tolist() + elif element == "valve": + hoverinfo = ( + "Index: " + net.valve.index.astype(str) + "
" + + "Name: " + net.valve['name'].astype(str) + "
" + + "Open: " + net.valve['opened'].astype(str) + "
" + + "Diameter: " + ((net.valve['diameter_m']).round(precision)*1e3).astype(str) + + " mm
" + ).tolist() + else: + return None + hoverinfo = pd.Series(index=hover_index, data=hoverinfo) + if sub_index is not None: + hoverinfo = hoverinfo.loc[list(sub_index)] + return hoverinfo + + +def simple_plotly(net, use_pipe_geodata=None, on_map=False, + projection=None, map_style='basic', figsize=1, aspectratio='auto', pipe_width=1, + junction_size=10, ext_grid_size=20.0, valve_size=3.0, compressor_size=3, + junction_color="blue", pipe_color='grey', pressure_reg_color='green', + ext_grid_color="yellow", valve_color="black", compressor_color="cyan", + filename='temp-plot.html', + auto_open=True, showlegend=True, additional_traces=None): + respect_valves = False # TODO, not implemented yet + node_element = "junction" + branch_element = "pipe" + trans_element = "pump" + separator_element = "valve" + + traces, settings = _simple_plotly_generic(net=net, + respect_separators=respect_valves, + use_branch_geodata=use_pipe_geodata, + on_map=on_map, + projection=projection, + map_style=map_style, + figsize=figsize, + aspectratio=aspectratio, + branch_width=pipe_width, + node_size=junction_size, + ext_grid_size=ext_grid_size, + node_color=junction_color, + branch_color=pipe_color, + trafo_color=pressure_reg_color, + trafo3w_color=pressure_reg_color, + ext_grid_color=ext_grid_color, + node_element=node_element, + branch_element=branch_element, + trans_element=trans_element, + trans3w_element=None, + separator_element=separator_element, + branch_trace_func=create_pipe_trace, + node_trace_func=create_junction_trace, + hoverinfo_func=get_hoverinfo, + filename=filename, + auto_open=auto_open, + showlegend=showlegend) + if "valve" in net.keys() and len(net.valve) > 0: + if "source_name" in net.valve.columns: + info = net.valve.apply(lambda x: f"{x['name']}
{x['source_name']}", axis=1) + else: + info = None + traces.extend(create_valve_trace(net, valves=net.valve.loc[net.valve.opened].index, + size=valve_size, color=valve_color, + infofunc=info, + trace_name="open valves")) + traces.extend(create_valve_trace(net, valves=net.valve.loc[~net.valve.opened].index, + size=valve_size, color=valve_color, dash="dot", + infofunc=info, + trace_name="closed valves")) + + if "compressor" in net.keys() and len(net.compressor) > 0: + traces.extend(create_compressor_trace(net, size=compressor_size, color=compressor_color)) + if "press_control" in net.keys() and len(net.press_control) > 0: + traces.extend( + create_press_control_trace(net, size=compressor_size, color="cyan", + trace_name='compressors SPO', + legendgroup='compressors SPO')) + traces.extend(create_junction_trace(net, net.press_control.controlled_junction.values, + color="red", size=10, + trace_name="controlled junction", + legendgroup='compressors SPO')) + if additional_traces: + if isinstance(additional_traces, dict): + traces.append(additional_traces) + else: + traces.extend(additional_traces) + + return draw_traces(traces, **settings) + + +if __name__ == '__main__': + from pandapipes.networks import gas_versatility + net = gas_versatility() + simple_plotly(net) diff --git a/pandapipes/plotting/plotly/traces.py b/pandapipes/plotting/plotly/traces.py new file mode 100644 index 00000000..8e487114 --- /dev/null +++ b/pandapipes/plotting/plotly/traces.py @@ -0,0 +1,113 @@ +# Copyright (c) 2022 by Fraunhofer Institute for Energy Economics +# and Energy System Technology (IEE), Kassel, and University of Kassel. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. + +from pandapower.plotting.plotly.traces import _create_node_trace, _create_branch_trace, \ + draw_traces + + +def create_junction_trace(net, junctions=None, size=5, patch_type="circle", color="blue", + infofunc=None, trace_name='junctions', legendgroup=None, cmap=None, + cmap_vals=None, cbar_title=None, cmin=None, cmax=None, cpos=1.0, + colormap_column="p_bar"): + + node_element = "junction" + branch_element = "pipe" + + return _create_node_trace(net=net, nodes=junctions, size=size , patch_type=patch_type, + color=color, infofunc=infofunc, trace_name=trace_name, + legendgroup=legendgroup, cmap=cmap, cmap_vals=cmap_vals, + cbar_title=cbar_title, cmin=cmin, cmax=cmax, cpos=cpos, + colormap_column=colormap_column, + node_element=node_element, branch_element=branch_element) + + +def create_pipe_trace(net, pipes=None, use_pipe_geodata=True, respect_valves=False, width=1.0, + color='grey', infofunc=None, trace_name='pipes', legendgroup='pipes', + cmap=None, cbar_title=None, show_colorbar=True, cmap_vals=None, cmin=None, + cmax=None, cpos=1.1): + branch_element = "pipe" + node_element = "junction" + separator_element = "valve" + + return _create_branch_trace(net=net, branches=pipes, use_branch_geodata=use_pipe_geodata, + respect_separators=respect_valves, width=width, color=color, + infofunc=infofunc, trace_name=trace_name, legendgroup=legendgroup, + cmap=cmap, cbar_title=cbar_title, show_colorbar=show_colorbar, + cmap_vals=cmap_vals, cmin=cmin, cmax=cmax, cpos=cpos, + branch_element=branch_element, separator_element=separator_element, + node_element=node_element, cmap_vals_category="vmean_m_s") + + +def create_valve_trace(net, valves=None, use_valve_geodata=False, size=1.0, + color='black', infofunc=None, trace_name='valves', legendgroup='valves', + dash="solid"): + branch_element = "valve" + node_element = "junction" + separator_element = "valve" + respect_valves = False + cmap = None + cbar_title = None + show_colorbar = True + cmap_vals = None + cmin = None + cmax = None + cpos = 1.1 + + return _create_branch_trace(net=net, branches=valves, use_branch_geodata=use_valve_geodata, + respect_separators=respect_valves, width=size, color=color, + infofunc=infofunc, trace_name=trace_name, legendgroup=legendgroup, + cmap=cmap, cbar_title=cbar_title, show_colorbar=show_colorbar, + cmap_vals=cmap_vals, cmin=cmin, cmax=cmax, cpos=cpos, + branch_element=branch_element, separator_element=separator_element, + node_element=node_element, cmap_vals_category="vmean_m_s", + dash=dash) + + +def create_compressor_trace(net, compressors=None, use_pipe_geodata=False, size=3.0, + color='cyan', infofunc=None, trace_name='compressors', + legendgroup='compressors'): + branch_element = "compressor" + node_element = "junction" + separator_element = "valve" + respect_valves = False + cmap = None + cbar_title = None + show_colorbar = True + cmap_vals = None + cmin = None + cmax = None + cpos = 1.1 + + return _create_branch_trace(net=net, branches=compressors, use_branch_geodata=use_pipe_geodata, + respect_separators=respect_valves, width=size, color=color, + infofunc=infofunc, trace_name=trace_name, legendgroup=legendgroup, + cmap=cmap, cbar_title=cbar_title, show_colorbar=show_colorbar, + cmap_vals=cmap_vals, cmin=cmin, cmax=cmax, cpos=cpos, + branch_element=branch_element, separator_element=separator_element, + node_element=node_element, cmap_vals_category="compr_power_mw") + + +def create_press_control_trace(net, compressors=None, size=3.0, + color='cyan', infofunc=None, trace_name='pressure controller', + legendgroup='pressure controller'): + branch_element = "press_control" + node_element = "junction" + separator_element = "valve" + respect_valves = False + cmap = None + cbar_title = None + show_colorbar = True + cmap_vals = None + cmin = None + cmax = None + cpos = 1.1 + use_pipe_geodata = False + + return _create_branch_trace(net=net, branches=compressors, use_branch_geodata=use_pipe_geodata, + respect_separators=respect_valves, width=size, color=color, + infofunc=infofunc, trace_name=trace_name, legendgroup=legendgroup, + cmap=cmap, cbar_title=cbar_title, show_colorbar=show_colorbar, + cmap_vals=cmap_vals, cmin=cmin, cmax=cmax, cpos=cpos, + branch_element=branch_element, separator_element=separator_element, + node_element=node_element, cmap_vals_category="controlled_p_bar")