How to Create a Gauge Chart Using Python ?

Introduction

Gauge charts are ideal for displaying a single metric such as system performance, CPU usage, or progress toward a goal.
They visually represent how a value compares to defined ranges or thresholds, making them particularly effective for dashboards and monitoring applications.

In Python, gauge charts can be created using several libraries depending on your needs:

  • Plotly: interactive and ready to use in notebooks or dashboards
  • Matplotlib: static and highly customizable, ideal for publications
  • Dash: for live, interactive web apps that can update in real time

Below we’ll go through each approach, from simple static visualizations to real-time interactive dashboards.

Using Plotly

Plotly provides a dedicated chart type for gauges via the go.Indicator object.
It combines numeric indicators and gauge arcs, with built-in support for color segments, threshold markers, and labels.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import plotly.graph_objects as go

value = 75

fig = go.Figure(go.Indicator(
    mode = "gauge+number",
    value = value,
    title = {
        'text': "System Performance",
        'font': {'size': 22, 'color': '#2F4F4F'}  # dark slate gray
    },
    number = {'font': {'size': 40, 'color': '#2F4F4F'}},
    gauge = {
        'axis': {
            'range': [0, 100],
            'tickwidth': 1,
            'tickcolor': '#A9A9A9'
        },
        'bar': {'color': '#4C78A8'},  # muted blue for the needle bar
        'bgcolor': 'white',
        'borderwidth': 1.5,
        'bordercolor': '#D3D3D3',
        'steps': [
            {'range': [0, 50], 'color': '#E5E8E8'},   # light gray
            {'range': [50, 80], 'color': '#C8D6E5'},  # pale blue-gray
            {'range': [80, 100], 'color': '#A3C1AD'}  # desaturated green
        ],
        'threshold': {
            'line': {'color': '#FF6F61', 'width': 4},  # muted coral
            'thickness': 0.75,
            'value': 90
        }
    }
))

fig.update_layout(
    paper_bgcolor='white',
    font={'color': '#2F4F4F', 'family': 'Arial'},
)

fig.show()

Explanation:
This example creates a smooth, minimalistic gauge with three color bands representing performance ranges.
The threshold highlights a critical value (90), while the muted blue needle and light palette ensure readability in professional dashboards.

Features:

  • Built-in gauge support via go.Indicator
  • Fully interactive in Jupyter, VS Code, or web dashboards
  • Easily customizable color segments, fonts, and thresholds

How to Create a Gauge Chart Using Python ?
How to Create a Gauge Chart Using Python ?

Using Matplotlib (Static, More Control)

If you prefer static charts or need publication-quality figures, Matplotlib provides full control.
While it doesn’t include a dedicated gauge type, we can build one using arcs (patches.Wedge) and polar geometry.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import matplotlib.pyplot as plt
import matplotlib.patches as patches
import numpy as np

def gauge_chart(value, title='System Performance', min_val=0, max_val=100):
    # Clamp the input value
    value = max(min_val, min(max_val, value))

    # Convert value to angular position (0° = max, 180° = min)
    def val_to_deg(v):
        return 180.0 * (1.0 - (v - min_val) / (max_val - min_val))

    fig, ax = plt.subplots(figsize=(6, 3))
    ax.set_aspect('equal')

    # Define geometry
    outer_r = 1.0
    thickness = 0.30
    inner_r = outer_r - thickness

    # Color zones
    zones = [
        (0, 50, '#E5E8E8'),   # light gray
        (50, 80, '#C8D6E5'),  # pale blue-gray
        (80, 100, '#A3C1AD')  # desaturated green
    ]

    # Draw each zone as a wedge
    for a, b, color in zones:
        theta1 = val_to_deg(b)
        theta2 = val_to_deg(a)
        wedge = patches.Wedge(center=(0, 0), r=outer_r,
                              theta1=theta1, theta2=theta2,
                              width=thickness,
                              facecolor=color, edgecolor='white', linewidth=1)
        ax.add_patch(wedge)

    # Subtle border behind the arc
    bg_wedge = patches.Wedge(center=(0, 0), r=outer_r + 0.01,
                             theta1=0, theta2=180, width=thickness + 0.02,
                             facecolor='none', edgecolor='#DDDDDD', linewidth=1)
    ax.add_patch(bg_wedge)

    # Draw the needle
    angle_deg = val_to_deg(value)
    angle_rad = np.deg2rad(angle_deg)
    needle_len = inner_r + thickness * 0.9
    nx, ny = needle_len * np.cos(angle_rad), needle_len * np.sin(angle_rad)
    ax.plot([0, nx], [0, ny], lw=3.5, color='#4C78A8', zorder=5)
    ax.scatter([0], [0], s=120, color='#2F4F4F', zorder=6)

    # Threshold marker (at 90%)
    threshold = 90
    th_deg = val_to_deg(threshold)
    th_rad = np.deg2rad(th_deg)
    t_outer, t_inner = outer_r + 0.01, outer_r - 0.02
    tx1, ty1 = t_inner * np.cos(th_rad), t_inner * np.sin(th_rad)
    tx2, ty2 = t_outer * np.cos(th_rad), t_outer * np.sin(th_rad)
    ax.plot([tx1, tx2], [ty1, ty2], lw=3, color='#FF6F61', zorder=7, solid_capstyle='round')

    # Labels and text
    ax.text(0, -0.20, f'{value:.0f}%', ha='center', va='center',
            fontsize=28, fontweight='bold', color='#2F4F4F')
    ax.text(0, -0.36, title, ha='center', va='center',
            fontsize=12, color='#2F4F4F')

    # Tick labels (0, 50, 100)
    for tick in [min_val, (min_val + max_val) / 2, max_val]:
        d = val_to_deg(tick)
        r_tick = outer_r + 0.07
        x, y = r_tick * np.cos(np.deg2rad(d)), r_tick * np.sin(np.deg2rad(d))
        ax.text(x, y, f'{int(tick)}', ha='center', va='center', fontsize=10, color='#666666')

    ax.set_xlim(-1.15, 1.15)
    ax.set_ylim(-0.35, 1.15)
    ax.axis('off')
    plt.tight_layout()
    plt.show()

# Example
gauge_chart(75, title='System Performance')

Explanation:
Here, the gauge is constructed from wedges and trigonometric angles.
This approach allows fine-grained control over every visual element (e.g., radius, border width, or colors), making it ideal for reports or publications.

How to Create a Gauge Chart Using Python ?
How to Create a Gauge Chart Using Python ?

Using Dash (for Web Apps)

To bring your gauge charts to the web or a monitoring dashboard, you can use Dash, which integrates seamlessly with Plotly figures.

Here’s a basic Dash setup displaying a static gauge:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
from dash import Dash, dcc, html
import plotly.graph_objects as go

app = Dash(__name__)

fig = go.Figure(go.Indicator(
    mode = "gauge+number",
    value = 72,
    title = {'text': "CPU Usage"},
    gauge = {'axis': {'range': [0, 100]}}
))

app.layout = html.Div([
    html.H2("Real-time Gauge Example"),
    dcc.Graph(figure=fig)
])

if __name__ == '__main__':
    app.run_server(debug=True)

Explanation:
This example sets up a minimal dashboard with a single Plotly gauge embedded inside a Dash layout.
Running it locally launches an interactive web app at http://127.0.0.1:8050.

How to Create a Gauge Chart Using Python ?
How to Create a Gauge Chart Using Python ?

Improved Dash Gauge App (Polished UI + Real-time Option Ready)

This enhanced version demonstrates dynamic updating, suitable for real-time metrics like CPU usage or sensor data.
It uses dcc.Interval to refresh the gauge periodically.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
from dash import Dash, dcc, html
from dash.dependencies import Input, Output
import plotly.graph_objects as go
import random

# ----------------------------
# Create Dash app
# ----------------------------
app = Dash(__name__)
app.title = "System Monitor"

# ----------------------------
# Define gauge figure (base style)
# ----------------------------
def create_gauge(value):
    fig = go.Figure(go.Indicator(
        mode="gauge+number",
        value=value,
        title={'text': "CPU Usage", 'font': {'size': 22, 'color': '#2F4F4F'}},
        number={'font': {'size': 36, 'color': '#2F4F4F'}},
        gauge={
            'axis': {'range': [0, 100], 'tickwidth': 1, 'tickcolor': '#A9A9A9'},
            'bar': {'color': '#4C78A8'},  # muted blue
            'bgcolor': 'white',
            'borderwidth': 1.5,
            'bordercolor': '#D3D3D3',
            'steps': [
                {'range': [0, 50], 'color': '#E5E8E8'},
                {'range': [50, 80], 'color': '#C8D6E5'},
                {'range': [80, 100], 'color': '#A3C1AD'}
            ],
            'threshold': {
                'line': {'color': '#FF6F61', 'width': 4},
                'thickness': 0.75,
                'value': 90
            }
        }
    ))

    fig.update_layout(
        margin=dict(l=20, r=20, t=60, b=20),
        paper_bgcolor='white',
        font={'color': '#2F4F4F', 'family': 'Arial'}
    )
    return fig

# ----------------------------
# Layout
# ----------------------------
app.layout = html.Div([
    html.H2("Real-Time Gauge Example", 
            style={'textAlign': 'center', 'color': '#2F4F4F', 'marginBottom': '20px'}),

    dcc.Graph(id='gauge-graph', figure=create_gauge(72), 
              style={'height': '70vh', 'width': '60%', 'margin': 'auto'}),

    # Refresh every second (simulate real-time)
    dcc.Interval(id='interval', interval=1000, n_intervals=0)
],
style={
    'backgroundColor': 'white',
    'display': 'flex',
    'flexDirection': 'column',
    'alignItems': 'center',
    'justifyContent': 'center',
    'height': '100vh'
})

# ----------------------------
# Callback for real-time updates
# ----------------------------
@app.callback(
    Output('gauge-graph', 'figure'),
    Input('interval', 'n_intervals')
)
def update_gauge(n):
    # Simulate dynamic CPU usage
    new_value = random.randint(40, 95)
    return create_gauge(new_value)

# ----------------------------
# Run app
# ----------------------------
if __name__ == '__main__':
    app.run_server(debug=True)

Explanation:
This app uses the dcc.Interval component to update the gauge each second, simulating a live data stream.
The layout is minimalist, centered, and easily customizable — perfect for system monitoring dashboards.

How to Create a Gauge Chart Using Python ? How to Create a Gauge Chart Using Python ?
How to Create a Gauge Chart Using Python ?

References

Links Site
Plotly Indicator (Gauge) documentation Plotly official site
Plotly go.Indicator API reference Plotly GitHub documentation
Plotly Gauge charts (with steps and threshold) Plotly official examples
Dash dcc.Graph component Dash documentation
Dash dcc.Interval component Dash documentation
Dash Layout and Callbacks Dash official guide
Dash HTML Components Dash documentation
Image

of