Hello,
I’m using Dash Plotly to build a dashboard to display real time data for an application I am building. My team designed a dial to use for the dashboard as pictured below (in the middle would be the actual value it is reading):
I tried building this dial using daq.Gauge
but it seemed a bit problematic because I couldn’t figure out how to get rid of the needle and the little numbers that were inside of the gauge’s circle. I then tried using plotly.graph_objects
to create an indicator graph that utilizes a gauge. Although it isn’t a one-to-one creation of the original design, it got close enough, however, I’m struggling to figure out how to change the threshold shape from a line to a triangle. Below is a picture of what I have right now.
This is the code I used to generate this
import random
import dash
from dash import dcc, html
from dash.dependencies import Input, Output
import dash_bootstrap_components as dbc
import plotly.graph_objects as go
import dash_daq as daq
app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
# func to create a custom gauge with a label
def create_gauge(gauge_id, label_text, value=5):
fig = go.Figure(
go.Indicator(
mode="gauge+number",
value=value,
gauge={
"shape": "angular",
"axis": {"range": [0, 10]},
"bar": {"color": "#FFA07A"}, # Use black to hide the bar
"bgcolor": "#FFA07A",
"threshold": {
"line": {"color": "#800020", "width": 4},
"thickness": 0.75,
"value": value,
},
},
domain={"x": [0, 1], "y": [0, 1]},
)
)
fig.update_layout(
margin=dict(l=20, r=20, t=50, b=20),
height=200,
)
return html.Div(
[
dcc.Graph(id=gauge_id, figure=fig, config={"staticPlot": True}),
html.P(label_text, style={"text-align": "center", "margin-top": "5px"}),
]
)
# layout of the dashboard
app.layout = dbc.Container(
[
html.H1("Custom Gauge Example"),
dbc.Row(
[
dbc.Col(
[
html.Div("Custom Gauge with Plotly"),
create_gauge("custom-gauge1", "Speed"),
create_gauge("custom-gauge2", "Temperature"),
create_gauge("custom-gauge3", "Pressure"),
]
),
dcc.Interval(
id="interval-component",
interval=200, # update every 200 milliseconds
n_intervals=0,
),
]
),
],
fluid=True,
)
# Create a callback to update the gauges
@app.callback(
[
Output("custom-gauge1", "figure"),
Output("custom-gauge2", "figure"),
Output("custom-gauge3", "figure"),
],
[Input("interval-component", "n_intervals")],
)
def update_gauges(n):
# simulate data update, replace with actual data retrieval
new_values = [random.uniform(0, 10) for _ in range(3)]
gauges = []
for value in new_values:
fig = go.Figure(
go.Indicator(
mode="gauge+number",
value=value,
gauge={
"shape": "angular",
"axis": {"range": [0, 10]},
"bar": {"color": "#FFA07A"},
"bgcolor": "#FFA07A",
"threshold": {
"line": {"color": "#800020", "width": 4},
"thickness": 0.75,
"value": value,
},
},
domain={"x": [0, 1], "y": [0, 1]},
)
)
fig.update_layout(
margin=dict(l=20, r=20, t=50, b=20),
height=200,
)
gauges.append(fig)
return gauges
if __name__ == "__main__":
app.run_server(debug=True)
Any insight on this issue would be much appreciated.