Visualization

This guide explains how to visualize water distribution networks using the ScenarioVisualizer class.

The ScenarioVisualizer class allows for generating plots, animations and customizations, according to the ScadaData generated by the ScenarioSimulator.

Setup and basic visualization

In order to setup a new ScenarioVisualizer instance, we first have to create a new ScenarioSimulator instance.

The ScenarioSimulator instance is then provided to the ScenarioVisualizer.

# Load a network configuration and create a ScenarioSimulator with it
network_config = load_anytown(verbose=False)
with ScenarioSimulator(scenario_config=network_config) as wdn:
    # Create a ScenarioVisualizer object and show the network topology plot
    vis = ScenarioVisualizer(wdn)
    vis.show_plot()

The show_plot() method visualizes the network:

_images/anytown_plot.png

Note

Alternatively, you can use the plot_topology() function of a ScenarioSimulator instance.

Customization

The hydraulic components can be colored according to the simulation results by calling the corresponding methods:

The ScadaData is generated inside the methods using the provided ScenarioSimulator instance from initialization, but it can also be set explicitly by setting the scada_data attribute.

The two main arguments for customization are called parameter and statistic. Parameter refers to which data to use for coloring and the statistic refers to the processing of that data. Both are supplied as string.

The parameter options depend on the hydraulic component and are listed with their data source in the following table:

Node parameter

Corresponding data source

pressure

pressure_data_raw

demand

demand_data_raw

node_quality

node_quality_data_raw

Link parameter

Corresponding data source

flow_rate

flow_data_raw

link_quality

link_quality_data_raw

diameter

get_link_info()

Pump parameter

Corresponding data source

efficiency

pumps_efficiency_data_raw

energy_consumption

pumps_energyconsumption_data_raw

state

pumps_state_data_raw

Tank parameter

Corresponding data source

default

tanks_volume_data_raw

Valve parameter

Corresponding data source

default

valves_state_data_raw

Note

In the case, that the sensor data (instead of raw data) should be visualized, the parameter use_sensor_data should be set to True. The sensor values may include sensor faults or noise and are only available when there is a corresponding sensor attached to the component, if that is not the case, the component is displayed using its default color.

The statistic decides how the simulation data over time is processed to one value which can be displayed. It has the following options:

  • mean

  • min

  • max

  • time_step

If time_step is selected, the point in time must be provided via the pit parameter.

Note

Example: When calling color_nodes() with the parameter pressure and the statistic max, each node in the network is colored according to its maximum pressure value during the simulation time.

Here are two examples:

# Load a network configuration and create a ScenarioSimulator with it
network_config = load_anytown(verbose=False)
with ScenarioSimulator(scenario_config=network_config) as wdn:
    vis = ScenarioVisualizer(wdn, color_scheme=black_colors)

    # Color nodes according to the pressure at time step 8
    vis.color_nodes(parameter='pressure', statistic='time_step', pit=8,
                    colormap='autumn', show_colorbar=True)
    vis.show_plot()
_images/anytown_pressure_plot.png
# Load a network configuration and create a ScenarioSimulator with it
network_config = load_anytown(verbose=False)
with ScenarioSimulator(scenario_config=network_config) as wdn:
    vis = ScenarioVisualizer(wdn, color_scheme=black_colors)

    # Color the pumps according to the maximum energy consumption during the simulation time
    vis.color_pumps(parameter='energy_consumption', statistic='max',
                    show_colorbar=True)

    # Color the links according to the mean flow rate
    vis.color_links(parameter='flow_rate', statistic='mean',
                    show_colorbar=True)

    vis.show_plot()
_images/anytown_flow_rate_plot.png

If show_colorbar is true, a colorbar is generated and displayed in the plot.

The black_colors color scheme sets all hydraulic components’ default color to black.

Method calls can be combined to adjust multiple components before rendering, such that each component is colored according to the given parameter and statistic. If multiple calls to the same component are made, only the last call is valid.

Further customization options are the following:

  1. colormap: The colormap defines the range of colors used for displaying high and low values. It can be provided as an argument. The options are matplotlib.colors.Colormap names, such as ‘viridis’, ‘coolwarm’ or ‘autumn’.

  2. hide_nodes(): It is possible to hide the nodes by calling the method hide_nodes()

  3. resize_links(): Links can also be sized according to a parameter and statistic by calling the function resize_links(). It can be called independently to color_links() and they can be combined.

Animation

It is possible to animate the values over the time steps. For this, the following 3 steps are necessary:

  1. Set the statistic to ‘time_step’

  2. Set the pit to a tuple of two values: (start_time_step, end_time_step)

  3. Call show_animation() instead of show_plot()

This code shows an animation of the links by coloring and sizing them using generated custom data over time. The pit (0, -1) animates all available time steps.

# Load a network configuration and create a ScenarioSimulator with it
network_config = load_anytown(verbose=False)
with ScenarioSimulator(scenario_config=network_config) as wdn:
    # Generate custom data for better demonstration
    timesteps = 50
    links = 41
    t = np.linspace(0, 2 * np.pi, timesteps)

    frequencies = np.linspace(1, 3, links)
    phases = np.linspace(0, np.pi, links)
    amplitudes = np.linspace(0.5, 1.5, links)

    custom_data_table = np.array([a * np.sin(f * t + p) for f, p, a in
                                zip(frequencies, phases, amplitudes)]).T

    # Create new ScenarioVisualizer with black color scheme
    vis = ScenarioVisualizer(wdn, color_scheme=black_colors)

    # Visualize the custom data from time step 0 to the last time step (-1) as
    # link color and link size
    vis.color_links(data=custom_data_table, parameter='custom_data',
                    statistic='time_step', pit=(0, -1))
    vis.resize_links(data=custom_data_table, parameter='custom_data',
                     statistic='time_step', pit=(0, -1), line_widths=(1, 3))

    # Hide the nodes such that only the links remain visible
    vis.hide_nodes()
    vis.show_animation()

Saving the visualization

The generated plots can be saved by setting the export_to_file argument with the desired filename. The file type must be compatible with matplotlib (e.g. .png, .jpg for images, .mp4 for videos).

vis.show_plot(export_to_file='network_plot.png')

The same argument exists for the animation:

vis.show_animation(export_to_file='network_animation.mp4')

In order to display the animation in a jupyter notebook, the FuncAnimation instance can be returned and displayed like this:

from IPython.display import HTML

# Create a FuncAnimation object
anim = vis.show_animation(return_animation=True)
# Display animation in jupyter notebook
HTML(anim.to_jshtml())