How to plot simulation results¶
The simulation module provides pluggable plotting backends for visualizing results with matplotlib or plotly.
Not in JavaScript yet
Plotting simulation results is available in Python and is not in JavaScript today. A temporary gap, not a boundary. The port is tracked in idfkit-js#24.
The full entry, including the vocabulary this capability owns, is on the capability parity page.
Quick Start¶
from idfkit.simulation import simulate
result = simulate(model, weather)
# Plot time series
ts = result.sql.get_timeseries(
"Zone Mean Air Temperature",
"ZONE 1",
)
fig = ts.plot() # Auto-detects available backend
Installation¶
Install a plotting backend:
# Matplotlib (recommended for static plots)
pip install idfkit[plot]
# Plotly (for interactive plots)
pip install idfkit[plotly]
# Both
pip install idfkit[plot,plotly]
Built-in Visualizations¶
Each of these takes the SQL database from a completed run, result.sql,
shown below as sql.
Temperature Profile¶
from idfkit.simulation import plot_temperature_profile
# `sql` is result.sql from a completed simulation
fig = plot_temperature_profile(
sql,
["THERMAL ZONE 1", "THERMAL ZONE 2"],
title="Zone Temperatures",
)
Energy Balance¶
from idfkit.simulation import plot_energy_balance
# `sql` is result.sql from a completed simulation
fig = plot_energy_balance(
sql,
title="Annual Energy Balance",
)
Comfort Hours¶
from idfkit.simulation import plot_comfort_hours
# `sql` is result.sql from a completed simulation
fig = plot_comfort_hours(
sql,
["THERMAL ZONE 1"],
title="Thermal Comfort Analysis",
)
Time Series Plotting¶
TimeSeriesResult has a built-in plot() method:
ts = result.sql.get_timeseries(
"Zone Mean Air Temperature",
"ZONE 1",
)
# Default plot
fig = ts.plot()
# Custom title
fig = ts.plot(title="My Custom Title")
# Explicit backend
from idfkit.simulation.plotting.matplotlib import MatplotlibBackend
fig = ts.plot(backend=MatplotlibBackend())
Backend Selection¶
Auto-Detection¶
By default, the first available backend is used:
from idfkit.simulation import get_default_backend
backend = get_default_backend()
print(type(backend).__name__) # MatplotlibBackend or PlotlyBackend
Priority: matplotlib → plotly
Explicit Backend¶
from idfkit.simulation.plotting.matplotlib import MatplotlibBackend
from idfkit.simulation.plotting.plotly import PlotlyBackend
# Force matplotlib
fig = ts.plot(backend=MatplotlibBackend())
# Force plotly
fig = ts.plot(backend=PlotlyBackend())
PlotBackend Protocol¶
Create custom backends by implementing the PlotBackend protocol:
from idfkit.simulation import PlotBackend
class MyBackend(PlotBackend):
def line(
self,
x: list,
y: list,
*,
title: str = "",
xlabel: str = "",
ylabel: str = "",
label: str | None = None,
):
# Return a figure object
...
def bar(
self,
categories: list[str],
values: list[float],
*,
title: str = "",
xlabel: str = "",
ylabel: str = "",
):
# Return a figure object
...
The backend classes live in their own modules so that importing
idfkit.simulation never pulls in matplotlib or plotly.
Matplotlib Backend¶
Basic Usage¶
from idfkit.simulation.plotting.matplotlib import MatplotlibBackend
backend = MatplotlibBackend()
fig = backend.line(
x=list(ts.timestamps),
y=list(ts.values),
title="Zone Temperature",
xlabel="Time",
ylabel="Temperature (°C)",
)
# Save to file
fig.savefig("temperature.png")
Customization¶
import matplotlib.pyplot as plt
# Create custom figure
fig, ax = plt.subplots(figsize=(12, 6))
# Plot multiple series
for zone_name in zone_names:
ts = result.sql.get_timeseries(
"Zone Mean Air Temperature",
zone_name,
)
ax.plot(ts.timestamps, ts.values, label=zone_name)
ax.legend()
ax.set_xlabel("Time")
ax.set_ylabel("Temperature (°C)")
plt.show()
Plotly Backend¶
Basic Usage¶
from idfkit.simulation.plotting.plotly import PlotlyBackend
backend = PlotlyBackend()
fig = backend.line(
x=list(ts.timestamps),
y=list(ts.values),
title="Zone Temperature",
)
# Interactive display
fig.show()
# Save to HTML
fig.write_html("temperature.html")
Customization¶
import plotly.graph_objects as go
fig = go.Figure()
for zone_name in zone_names:
ts = result.sql.get_timeseries(
"Zone Mean Air Temperature",
zone_name,
)
fig.add_trace(
go.Scatter(
x=list(ts.timestamps),
y=list(ts.values),
name=zone_name,
)
)
fig.update_layout(
title="Zone Temperatures",
xaxis_title="Time",
yaxis_title="Temperature (°C)",
)
fig.show()
DataFrame Integration¶
Convert to pandas and use native plotting:
# Get DataFrame
df = ts.to_dataframe()
# Matplotlib via pandas
df.plot(figsize=(12, 6))
# Plotly via pandas
import plotly.express as px
fig = px.line(df.reset_index(), x="timestamp", y=ts.variable_name)
Multiple Time Series¶
Same Variable, Multiple Keys¶
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
for zone_name in ["ZONE 1", "ZONE 2", "ZONE 3"]:
ts = result.sql.get_timeseries(
"Zone Mean Air Temperature",
zone_name,
)
ax.plot(ts.timestamps, ts.values, label=zone_name)
ax.legend()
plt.show()
Different Variables¶
fig, axes = plt.subplots(2, 1, figsize=(12, 8), sharex=True)
# Temperature
ts_temp = result.sql.get_timeseries("Zone Mean Air Temperature", "ZONE 1")
axes[0].plot(ts_temp.timestamps, ts_temp.values)
axes[0].set_ylabel("Temperature (°C)")
# Humidity
ts_rh = result.sql.get_timeseries("Zone Air Relative Humidity", "ZONE 1")
axes[1].plot(ts_rh.timestamps, ts_rh.values)
axes[1].set_ylabel("Relative Humidity (%)")
plt.tight_layout()
plt.show()
Saving Figures¶
Matplotlib¶
fig.savefig("plot.png", dpi=300, bbox_inches="tight")
fig.savefig("plot.pdf")
fig.savefig("plot.svg")
Plotly¶
fig.write_html("plot.html")
fig.write_image("plot.png") # Requires kaleido
fig.write_image("plot.pdf")
See Also¶
- How to query simulation SQL output — Getting time series data
- How to access simulation results — Working with SimulationResult
- Examples: Parametric Study — Visualization examples