plotly_figure
Displays a Plotly figure as an interactive HTML element.
We use Plotly under the hood to generate graphs. This component safely converts a python Figure to HTML, and optionally supports dynamic updates via HTMX.
Basic use¶
{% htmx_plotly_figure component.figure %}
import plotly.graph_objects as go
from simmate.website.htmx.components.base import HtmxComponent
class ExamplePlotComponent(HtmxComponent):
@property
def figure(self):
# Generate the figure to display
fig = go.Figure(data=go.Scatter(x=[1, 2, 3], y=[10, 15, 13]))
return fig
Parameters¶
| Parameter | Description |
|---|---|
figure |
The plotly.graph_objects.Figure object to render.Type: Figure, Default: — |
div_id |
The ID for the wrapping HTML div. Useful if you have multiple plots. If left as None while streaming, an ID will be generated automatically based on the component's ID.Type: str, Default: None |
stream_interval |
Interval (in seconds) to query the backend for new data and extend the traces. If None, no polling occurs.Type: int, Default: None |
stream_method |
The name of the backend method that returns the new data dictionary (e.g., {"x": [...], "y": [...]}). Only used if stream_interval is set.Type: str, Default: "get_new_data" |
max_points |
The maximum number of points to keep when streaming data to prevent memory overflow in the browser. Type: int, Default: 10000 |
Dynamic Updates¶
If you have data that changes over time (like monitoring lab equipment), HTMX allows for dynamic updates to your graph. There are two primary ways to do this:
1. Full Redraw (Easy way)¶
This approach completely replaces the figure element on a set interval using HTMX polling (htmx_refresh). It is simple to implement but less efficient for large datasets or frequent updates.
{% extends "htmx/form_base.html" %}
{% block form %}
<form class="m-0 p-0">
{% htmx_refresh refresh_loop="1s" indicator="None" %}
{% htmx_plotly_figure component.figure %}
</form>
{% endblock %}
import plotly.graph_objects as go
from simmate.website.htmx.components.base import HtmxComponent
class TemperaturePlotComponent(HtmxComponent):
template_name: str = "my_app/components/temperature_plot.html"
@property
def figure(self):
# Generate the latest figure. This is called on every refresh.
fig = go.Figure(data=go.Scatter(x=[1, 2, 3], y=[10, 15, 13]))
return fig
2. Streaming Update (Efficient way)¶
This approach uses Plotly's extendTraces functionality to append new data to the chart via JavaScript. This is much faster for large line/scatter plots and ideal for live dashboards. Both of these approaches can be seen in the lab automation app homepage.
{% extends "htmx/form_base.html" %}
{% block form %}
<form class="m-0 p-0">
<!--
We pass `stream_interval` which tells HTMX to poll for new data
using `stream_method` (default: get_new_data).
-->
{% htmx_plotly_figure component.figure stream_interval=1 %}
</form>
{% endblock %}
import plotly.graph_objects as go
from simmate.website.htmx.components.base import HtmxComponent
class StreamingTemperaturePlotComponent(HtmxComponent):
template_name: str = "my_app/components/streaming_plot.html"
@property
def figure(self):
# Generate the initial base figure. This is only called once.
fig = go.Figure(data=go.Scatter(x=[1, 2], y=[10, 15]))
return fig
def get_new_data(self) -> dict:
# Returns a dictionary of lists corresponding to new x/y data to append.
# This method is polled every `stream_interval` seconds.
return {
"x": [3],
"y": [13]
}