How to Make and Modify Terrific Gauge Charts Using Python Plotly
Three practical data visualizations using the Global Giving dataset
Gauge charts are terrific for visualizing a single value within a range at a glance.
Also known as dial or speedometer charts), gauge charts can be easily created using Python Plotly.
So let’s use a real dataset on global generosity to make things concrete. by walking through three examples of Plotly gauge charts with embedded Python code.
Each example demonstrates a different use case and customization for guage charts.
The Dataset
Our examples will use a dataset of global generosity metrics, the World Giving Index (found on my GitHub HERE).
This dataset is compiles as an annual survey (2011–2021) that measures the percentage of people in each country globally who engaged in certain charitable activities.
Each row of the dataset represents a country in a given year, and includes the following key fields:
Helping a stranger (%) — the proportion of people who helped a stranger in the past month.
Donating money (%) — the proportion of people who donated money to charity in the past month.
Volunteering time (%) — the proportion of people who volunteered their time for an organization in the past month.
Total Score (%) — an overall generosity score (essentially the average of the above three percentages).
Let’s use this dataset to create some useful and good-looking gauge charts with Plotly.
Example 1: Basic Gauge Chart for a Single Value
First, let’s create a basic gauge chart to display one value — the overall generosity score of a particular country.
This gauge chart will show a simple gauge from 0 to 100:
import plotly.graph_objects as go
import pandas as pd
df = pd.read_csv("all_generosity_data.csv")
# Extract the value for Indonesia's Total Score in 2021
value_str = df[(df["Country"] == "Indonesia") & (df["Year"] == 2021)]["Total Score"].iloc[0]
value = float(value_str.strip('%')) # convert "69%" to 69.0
# Create a basic gauge chart
fig = go.Figure(go.Indicator(
mode = "gauge+number",
value = value,
title = {"text": "Indonesia 2021 Generosity"},
gauge = {'axis': {'range': [0, 100]}}
))
fig.show()
In the code above, we use Plotly’s go.Indicator
trace with mode="gauge+number"
.
This displays a gauge (the dial) along with the numeric value. We set value
to the data we retrieved (69), and give the gauge a title.
The gauge.axis.range
is [0, 100]
since our percentages go from 0 to 100%. By calling fig.show()
, an interactive gauge chart will render, showing a half-circle dial labeled 0 to 100.
To run this code, I have loaded into Jupyter Notebook. One of the (many) awesome features of Jupyter Notebook is that it can render Python Plotly code on-the-fly — even Gauge Charts
Here’s a screen shot from my local Jupyter Notebook:
Awesome, looks great!
But more importantly, what does this chart tell us? It shows that Indonesia’s overall generosity score is 69%, which is quite high. The gauge’s needle pointing around the three-quarter mark of the dial gives a visual sense that this value is toward the upper end of the possible range.
And this basic gauge required minimal code (less than 10 lines!)
Plotly handled the rest!
Now that we have a basic understanding, let’s add some pizazz to our next gauge chart!
Example 2: Gauge Chart with Thresholds and Color Bands
Gauge charts become even more informative when we add context like color-coded ranges and threshold markers.
In this example, we’ll take Nigeria’s generosity score in 2021 (which was 52%) and create a gauge that highlights whether this value is low, medium, or high on our scale, and marks a specific target threshold.
Suppose we consider a “good” generosity score to be 50% or above. We will color-code the gauge in segments (e.g. red for low, yellow for moderate, green for high), and draw a threshold line at 50%.
This way, the gauge will clearly show which band Nigeria’s 52% falls into and that it has just crossed the target line.
import plotly.graph_objects as go
import pandas as pd
df = pd.read_csv("all_generosity_data.csv")
# Value for Nigeria's Total Score in 2021 (52%)
value_str = df[(df["Country"] == "Nigeria") & (df["Year"] == 2021)]["Total Score"].iloc[0]
value = float(value_str.strip('%')) # convert "52%" to 52.0
fig = go.Figure(go.Indicator(
mode = "gauge+number+delta",
value = value, # 52
delta = {'reference': 50, 'increasing': {'color': "blue"}},
title = {"text": "Nigeria 2021 Generosity"},
gauge = {
'axis': {'range': [0, 100]},
'bar': {'color': "blue"}, # <-- FIX: actual value bar is now blue
'steps': [
{'range': [0, 30], 'color': "red"},
{'range': [30, 50], 'color': "yellow"},
{'range': [50, 100], 'color': "green"}
],
'threshold': {
'line': {'color': "black", 'width': 4},
'thickness': 0.75,
'value': 50
}
}
))
fig.show()
Now the resulting gauge chart for Nigeria is much more illustrative than our previous example:
Wow, way more detail to look at here! We have divided the circular arc into coloured zones:
red for low values (below 30%),
yellow for medium (30–50%), and
green for high (50%+).
Nigeria’s value (52%) lies in the green zone, just above our 50% threshold.
We can use Plotly for even more customization — for example, we added delta={'reference': 50}
to the Indicator. This is a threshold marker. (shown in blue below the actual value) that displays the 2% above the target value.
Super cool!
Example 3: Comparing Metrics with Multiple Gauges
Our final example shows how to use multiple gauges together.
Gauge charts usually display one value, but you can arrange several gauges in a row to compare related values. In the generosity dataset, each country has three distinct metrics (helping strangers, donating money, volunteering time).
Let’s create a set of gauge charts that show how each of these components differ. For our example, let’s look at Liberia in 2018:
import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots
df = pd.read_csv("all_generosity_data.csv")
# Get Liberia's 2018 metrics
liberia_data = df[(df["Country"] == "Liberia") & (df["Year"] == 2018)].iloc[0]
help_val = float(liberia_data["Helping a stranger Score"].strip('%'))
donate_val = float(liberia_data["Donating money Score"].strip('%'))
vol_val = float(liberia_data["Volunteering time Score"].strip('%'))
# Set up a 1x3 subplot grid for three gauges
fig = make_subplots(
rows=1, cols=3, specs=[[{'type': 'domain'}]*3],
subplot_titles=["Helping a Stranger", "Donating Money", "Volunteering Time"]
)
# Add a gauge for each metric
fig.add_trace(go.Indicator(
mode="gauge+number",
value=help_val,
gauge={'axis': {'range': [0, 100]}},
title={'text': "Helping a Stranger"}
), row=1, col=1)
fig.add_trace(go.Indicator(
mode="gauge+number",
value=donate_val,
gauge={'axis': {'range': [0, 100]}},
title={'text': "Donating Money"}
), row=1, col=2)
fig.add_trace(go.Indicator(
mode="gauge+number",
value=vol_val,
gauge={'axis': {'range': [0, 100]}},
title={'text': "Volunteering Time"}
), row=1, col=3)
fig.update_layout(title_text="Liberia 2018 – Generosity Breakdown")
fig.show()
In this code, we used make_subplots
to create a layout with one row and three columns, each cell of type 'domain'
(which is appropriate for gauges). We then added three Indicator
traces to the figure, one for each metric, and placed them in the respective column.
Each gauge is set from 0 to 100%, and we give each a descriptive title.
The results from running the Python code:
Our visualization shows as a panel of three gauges side by side:
Helping a Stranger: ~80% — the gauge needle is deep in the green/high range, showing Liberia excelled in this category.
Donating Money: ~14% — the needle is in the red/low end, highlighting that very few people donated money.
Volunteering Time: ~47% — about mid-scale, a moderate volunteering rate.
Placing these gauges together makes it easy to compare the different dimensions of generosity.
For this particular year, Liberia’s overall score was 47%, but this was composed of a very high rate of helping strangers (80% of Liberians helped a stranger!), a modest volunteering rate (47%), and a very low donating money rate (only 14%).
What a great way to show how citizens of even a relatively poor country can be so helpful in other ways.
In Summary…
There are lot’s of options with Plotly gauge charts!
And with Plotly’s Python library, we can create these interactive gauges with just a few lines of code.
Using the World Giving Index data as an example, we demonstrated how to build a basic gauge, how to enhance it with qualitative ranges and targets, and how to combine gauges to compare multiple metrics.
These techniques can be applied to a single performance metric or a breakdown of several indicators.
Plotly gauges make your data visually appealing and instantly understandable.