High Impact Python Streamlit: Beautiful Interactive Maps and Charts
A step by step modular approach with UNFAO global food insecurity data
Recently, I have been working hard on coding Python Streamlit for interactive data visualizations - so that you don’t have to.
Specifically, I have been looking at how to put together interactive Streamlit dashboards - with a combination of visualizations.
Let me show you how you can create a Streamlit dashboard with:
A dropdown menu allowing the user to select the Year
Global Choropleth map by country(updated by year).
Horizontal bar chart of top 10 countries (updated by year)
Using a terrific public dataset, let’s put together a beautiful dashboard using a modular approach.
The Dataset — UN Global Food Insecurity
My wife works for the UN Food and Agriculture Organization and is responsible for making global decisions related to food insecurity.
To better understand the work that UNFAO does around food insecurity, let’s take a look at a new dataset (to me). The UN food security dataset can be found HERE.
After looking at the download interface, we can see that there are a few options to consider:
For the CSV file to download, we can choose all of the countries for all of the years available (2000–2022), along with 4 important indicators:
Prevalence of undernourishment (%)
Number of people undernourished (million)
Prevalence of severe food insecurity in the total population (%)
Number of severely food insecure people (million)
After downloading, we can save the file as UN_food_security.csv.
For this exercise, we are interested in creating a global choropleth map that displays the prevalence of food insecurity in the total population for each Year.
The relevant fields in our downloaded dataset are:
Area: The name of the geographical area, such as a country or region.
Item: The name or description of the item or indicator.
Year: The actual year or range of years as a string.
Unit: The unit of measurement for the data values.
Value: The data value.
On previewing the actual data, there are a few things to consider for the data:
Item — this is the indicator field that we specified during the download. We know that there are 4 indicators. We can decide which indicator(s) we want to show with our data visuals.
Year — This one is a bit tricky. It is shown as a “range of years” with the middle year being the “actual” year. We will need to kludge some code to handle this
Value — some of the data use a comparison operator (i.e.,>2.5). We need to have a way to handle this data. The simplest way is to just remove the operator.
Now that we know what needs to be “massaged” we can move on to the Python code.
Setting Up Our GPT-4 StreamLit Dashboard Project
To put it all together, let’s break this project down into steps:
Make sure we have all of the imported Python libraries installed
Initialize our Streamlit application (set the layout)
Read and preprocess the dataset to extract the necessary information.
Create a dropdown menu to allow the user to select the year.
Display a choropleth map for the selected year to show global food security values by country.
Display a horizontal bar chart for the countries with the highest levels of food insecurity for the selected year.
Our goal is to put all of these elements and visuals into a single dashboard using Streamlit.
Step 1. Importing Libraries
import streamlit as st
import pandas as pd
import plotly.express as px
For our interactive dashboard, we need three Python libraries:
streamlit
for building interactive web apps.pandas
for data manipulation and analysis.plotly.express
for creating interactive plots.
Step 2. Setting up our Streamlit App Layout
To initialize our Streamlit app correctly, for our first line of code, we need to set the layout for our app to “wide” (to fit in all of our dashboard elements):
st.set_page_config(layout="wide")
Step 3. Accessing and filtering the dataset
Next, we need to access and filter the UN food security dataset that we downloaded earlier. Let’s create a function called load_data() to do this for us:
# Load and preprocess data
def load_data():
data = pd.read_csv('UN_food_security.csv')
item_filter = "Prevalence of severe food insecurity in the total population (percent) (3-year average)"
filtered_data = data[data['Item'] == item_filter]
filtered_data['Year_Middle'] = filtered_data['Year'].apply(lambda x: int(x.split('-')[0]) + 1)
filtered_data['Value_Clean'] = pd.to_numeric(filtered_data['Value'].str.replace('<', '').replace('>', ''), errors='coerce')
filtered_data.dropna(subset=['Value_Clean'], inplace=True)
return filtered_data
data = load_data()
Just before our function, we want to first set our Streamlit layout (this needs to be done first). The function
The function load_data() performs several operations:
Reads a CSV file into a DataFrame.
Filters the data for a specific column value related to food insecurity.
Extracts and converts the start year of a range (e.g., “2010–2012”) to a single year.
Cleans and converts the ‘Value’ column to numeric, handling non-numeric symbols and missing values.
Returns the cleaned and filtered DataFrame.
Nice!
Now we can start to put together the pieces of the actual Streamlit application.
Step 4. Creating a Dropdown Menu
To start with let’s create the dropdown menu to allow the user to select a year:
# Streamlit app
st.title('Global Food Security Dashboard')
# Dropdown menu for year selection
years = data['Year_Middle'].unique()
selected_year = st.selectbox('Select Year', years)
# Filter data for the selected year
filtered_data_year = data[data['Year_Middle'] == selected_year]
Here we set the title for our streamlit app and create a dropdown menu for selecting a year. Earlier, we calculated the middle year of our data to include in our dataframe.
Now we want to display each year uniquely in our dropdown menu (computed from Year_Middle).
Lastly, we want to create a data frame (filtered_data_year) that includes only the data for the selected year.
We will display our bar chart and choropleth map from this new filtered data set.
Step 5. Drawing The Choropleth Map
Next, let’s create a map that displays the global situation for the selected year.
Drawing a choropleth map in Streamlit can be done using Python Plotly — specifically the express library:
fig_map = px.choropleth(filtered_data_year,
locations="Area",
locationmode="country names",
color="Value_Clean",
hover_name="Area",
hover_data={"Year_Middle": False, "Value_Clean": True},
color_continuous_scale="YlOrRd",
title="Global Food Insecurity")
st.plotly_chart(fig_map, use_container_width=True)
The express library has a built in method called choropleth() that accepts parameters for the data set, the location fields, the color (based on field data), the color scheme, and the title.
It configures map aesthetics and integrates it into the Streamlit page, adjusting the container width for better display.
Terrific. Now with the map drawn, the last step is to add on the horizontal bar chart.
Step 6. Drawing A Horizontal Bar Chart of Top 10 Countries
As with the previous visualization, we can use the Python Plotly Express library to access a method called bar() which will draw a bar chart for us:
# Horizontal bar chart on its own row, below the map
top_countries = filtered_data_year.nlargest(10, 'Value_Clean')
fig_bar = px.bar(top_countries,
x='Value_Clean',
y='Area',
orientation='h',
color='Value_Clean',
color_continuous_scale="YlOrRd",
title="Top Countries by Food Insecurity Level")
fig_bar.update_layout(yaxis={'categoryorder': 'total ascending'})
st.plotly_chart(fig_bar, use_container_width=True)
Before generating the bar chart, we first want to filter our data set one more level — to include only the top 10 most insecure countries for food safety. We can use the pandas nlargest() function to do this.
The bar() method generates a horizontal bar chart (orientation = ‘h’) displaying the top 10 countries with the highest food insecurity levels for the selected year.
It sets the layout and integrates the plot into Streamlit.
Running Our Streamlit Code
To run the code successfully, we want to make sure that we:
Have Streamlit, Pandas, and Plotly installed in our Python environment.
Are pointing to our CSV data set (correct path and name of our file.
Save the script as a
.py
file, for example,food_security_dashboard.py
.Run the script using the command
streamlit run [name_of_file.py]
in your terminal.
For my development environment, I use PyCharm. It has a built in Terminal window that I can open. From the command line, the command:
This will start the Streamlit application in your default web browser.
THE RESULT:
Here is our beautiful fully-functioning interactive Streamlit dashboard:
Beautiful and simple.
You can click on the dropdown menu to select a year. Both the map and the horizontal line chart are updated accordingly.
This is a useful and appealing dashboard for analyzing the global food security situation across a number of years.
Nice work putting this all together!
In Summary…
Yes, it is that quick, that simple, that easy. I’ve put in all the hard work working with Python Streamlit code — so that you don’t have to.
This entire interactive Streamlit dashboard — using a carefully structured modular approach
Thank you for reading.