Changing the Threshold Line in Gauges to a Triangle

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):

image

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.

image

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.

hi @bimm
That’s a great question. I don’t think that there is a built-in way to covert that line to a triangle. You defined all the possible attributes within the gauge_threshold. It looks like line is the only option.