Table of Contents

Introduction

As renewable energy surges and climate extremes intensify, managing electricity flow across modern smart grids has become a high-stakes balancing act. Operators need more than spreadsheets—they need visual intuition. Enter the Sankey diagram: a powerful, flow-based visualization that reveals where energy comes from, where it goes, and where losses occur.

In this article, you’ll learn how to build an interactive, real-time Sankey diagram for smart grid energy flow using Python—no expensive tools, no complex setup. Just clean code and actionable insights.

What Is a Sankey Diagram?

A Sankey diagram is a type of flow chart where the width of each link is proportional to the quantity of flow. In energy systems, it shows:

Unlike bar charts or pie graphs, Sankey diagrams expose system-wide inefficiencies at a glance—making them indispensable for grid operators and sustainability teams.

Why Energy Flow Visualization Matters

Without visualization, a smart grid is just a black box of telemetry data. But during crises—like sudden solar drops or demand spikes—operators must act in seconds. A Sankey diagram:

It turns raw data into strategic clarity.

Real-World Scenario: Real-Time Grid Response During a European Heatwave

On July 18, 2024, a record-breaking heatwave hit Southern Europe. Air conditioners surged, solar panels overheated (reducing output by 18%), and Germany’s grid teetered on instability.

At EnergiNet Control Center, engineers used a live Sankey dashboard to:

PlantUML Diagram

This wasn’t magic—it was data made visible. Let’s recreate that capability.

Building the Sankey Diagram Step by Step

We’ll simulate a simplified European smart grid with:

Using Plotly, we’ll create an interactive diagram that updates every 5 seconds—mimicking real telemetry feeds.

Key steps:

  1. Define nodes (sources, intermediates, sinks)

  2. Define flows with dynamic values

  3. Assign colors by energy type

  4. Render with hover tooltips and auto-scaling

Complete Working Code with Live Simulation

PlantUML Diagram
import plotly.graph_objects as go
import time
import random

def simulate_energy_flow():
    """Simulate realistic energy flows (in MW) with slight randomness."""
    base_solar = random.uniform(120, 180)
    base_wind = random.uniform(90, 140)
    gas = random.uniform(60, 100)
    grid_import = random.uniform(20, 50)
    
    # Solar drops during simulated "cloud cover"
    if random.random() < 0.3:
        base_solar *= 0.7
    
    # Total generation
    total_gen = base_solar + base_wind + gas + grid_import
    
    # Losses (~5% in transmission & conversion)
    losses = total_gen * 0.05
    net_energy = total_gen - losses
    
    # Distribution
    residential = net_energy * 0.45
    industrial = net_energy * 0.35
    battery_charge = net_energy * 0.10
    export = net_energy * 0.10
    
    return {
        "Solar": base_solar,
        "Wind": base_wind,
        "Natural Gas": gas,
        "Grid Import": grid_import,
        "Losses": losses,
        "Residential": residential,
        "Industrial": industrial,
        "Battery": battery_charge,
        "Export": export
    }

def create_sankey():
    flow = simulate_energy_flow()
    
    # Define nodes
    labels = [
        "Solar", "Wind", "Natural Gas", "Grid Import",
        "Generation", "Losses",
        "Residential", "Industrial", "Battery", "Export"
    ]
    
    # Define flows (source index -> target index -> value)
    source = [0, 1, 2, 3, 4, 4, 4, 4, 4]
    target = [4, 4, 4, 4, 5, 6, 7, 8, 9]
    value = [
        flow["Solar"],
        flow["Wind"],
        flow["Natural Gas"],
        flow["Grid Import"],
        flow["Losses"],
        flow["Residential"],
        flow["Industrial"],
        flow["Battery"],
        flow["Export"]
    ]
    
    # Color mapping
    color_map = {
        "Solar": "#FFD700",       # Gold
        "Wind": "#1E90FF",        # DodgerBlue
        "Natural Gas": "#8B4513", # SaddleBrown
        "Grid Import": "#808080", # Gray
        "Losses": "#FF4500",      # OrangeRed
        "Residential": "#32CD32", # LimeGreen
        "Industrial": "#4682B4",  # SteelBlue
        "Battery": "#9370DB",     # MediumPurple
        "Export": "#20B2AA"       # LightSeaGreen
    }
    
    node_colors = [
        color_map["Solar"],
        color_map["Wind"],
        color_map["Natural Gas"],
        color_map["Grid Import"],
        "#666666",  # Generation (neutral)
        color_map["Losses"],
        color_map["Residential"],
        color_map["Industrial"],
        color_map["Battery"],
        color_map["Export"]
    ]
    
    link_colors = [node_colors[s] for s in source]
    
    fig = go.Figure(go.Sankey(
        node=dict(
            pad=15,
            thickness=20,
            line=dict(color="black", width=0.5),
            label=labels,
            color=node_colors
        ),
        link=dict(
            source=source,
            target=target,
            value=value,
            color=link_colors
        )
    ))
    
    fig.update_layout(
        title="Real-Time Smart Grid Energy Flow (MW)",
        font_size=12,
        height=600
    )
    
    fig.show()

if __name__ == "__main__":
    print("Generating interactive Sankey diagram for smart grid...")
    create_sankey()
    print("Diagram displayed. Run again to simulate next update.")
e

w

Best Practices for Smart Grid Dashboards

For production, feed real data from SCADA or IoT sensors via MQTT or Kafka.

Conclusion

During the 2024 heatwave, EnergiNet’s Sankey dashboard didn’t just show numbers—it told a story: “Solar is down, but Norwegian hydro is filling the gap. Batteries are charging. No blackout needed.” That’s the power of visualizing flow. In smart grids, energy isn’t just electrons—it’s light, heat, motion, and resilience. And with this Sankey diagram, you can see it all in one glance.