Area chart
An area chart, like a line chart, displays the evolution of numeric variables over a continuous period of time. However, in an area chart, the area between the line and x-axis is filled with colour or texture.
More about: Area chart - Other tutorials: R D3
# import libraries
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
plt.style.use(['unhcrpyplotstyle', 'area'])
# Load and reshape the data
df = pd.read_csv('https://raw.githubusercontent.com/GDS-ODSSS/unhcr-dataviz-platform/master/data/change_over_time/area.csv')
df = df.pivot(index='year', columns='population_type', values='population_number')
df = df.reset_index()
# Compute data for plotting
x = df['year']
y = df['Refugees']
# Plot the chart
fig, ax = plt.subplots()
ax.stackplot(x, y, alpha=0.7)
# Set chart title
ax.set_title('Number of refugees | 1990-2021')
# Set y-axis label
ax.set_ylabel('Number of people (millions)')
# Format y-axis tick labels
def number_formatter(x, pos):
if x >= 1e6:
s = '{:1.0f}M'.format(x*1e-6)
elif x < 1e6 and x > 0:
s = '{:1.0f}K'.format(x*1e-3)
else:
s = '{:1.0f}'.format(x)
return s
ax.yaxis.set_major_formatter(number_formatter)
# Set chart source and copyright
plt.annotate('Source: UNHCR Refugee Data Finder', (0,0), (0, -25), xycoords='axes fraction', textcoords='offset points', va='top', color = '#666666', fontsize=9)
plt.annotate('©UNHCR, The UN Refugee Agency', (0,0), (0, -35), xycoords='axes fraction', textcoords='offset points', va='top', color = '#666666', fontsize=9)
# Adjust chart margin and layout
fig.tight_layout()
# Save the figure to the specified path
fig.savefig('plot/area-chart.png')
plt.show()
Dot plot
A dot plot is a type of graph in which the dots are connected to show changes or differences. It’s an alternative to the grouped bar chart or slope chart.
# import libraries
import matplotlib.pyplot as plt
import pandas as pd
from textwrap import wrap
plt.style.use(['unhcrpyplotstyle','dotplot'])
#load and reshape the data
df = pd.read_csv('https://raw.githubusercontent.com/GDS-ODSSS/unhcr-dataviz-platform/master/data/change_over_time/dot_plot.csv')
df = df.pivot_table(index=['location','order'], columns='period', values='percent', sort=False)
df = df.reset_index()
#sort values in descending order
ordered_df = df.sort_values(by='order', ascending=False)
#wrap the long labels
y_labels = ordered_df['location']
wrapped_label = [ '\n'.join(wrap(l, 20)) for l in y_labels ]
#plot the chart
fig, ax = plt.subplots()
plt.scatter(ordered_df['before_covid'], wrapped_label, label='before_covid')
plt.scatter(ordered_df['first_months'], wrapped_label, label='first_months')
plt.hlines(y=wrapped_label, xmin=ordered_df['before_covid'], xmax=ordered_df['first_months'], color='#666666')
#set chart legend
ax.legend(labels = ["Before COVID-19", "First month of the crisis"], loc=(0,1.05), ncol=2)
#set chart title
ax.set_title('COVID-19 impact on poverty rates of informal workers', pad=50)
# xticks and xticklabel format
limit = plt.xlim(0, 1)
vals = ax.get_xticks()
ax.set_xticks(vals)
ax.set_xticklabels(['{:,.0%}'.format(x) for x in vals])
#set chart source and copyright
plt.annotate('Source: UNHCR Refugee Data Finder', (0,0), (0, -25), xycoords='axes fraction', textcoords='offset points', va='top', color = '#666666', fontsize=9)
plt.annotate('©UNHCR, The UN Refugee Agency', (0,0), (0, -35), xycoords='axes fraction', textcoords='offset points', va='top', color = '#666666', fontsize=9)
#adjust chart margin and layout
fig.tight_layout()
# Save the figure to the specified path
fig.savefig('plot/dotplot.png')
#show chart
plt.show()
Line chart
A line chart is a type of chart that displays the evolution of one or several numeric variables over a continuous interval or time period. Typically, the x-axis is used for a timescale or a sequence of intervals, while the y-axis reports values across that progression.
More about: Line chart - Other tutorials: R D3
Single line chart
# import libraries
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
plt.style.use(['unhcrpyplotstyle','line'])
#compute data array for plotting
df = pd.read_csv('https://raw.githubusercontent.com/GDS-ODSSS/unhcr-dataviz-platform/master/data/change_over_time/line.csv')
df = df.pivot(index='year', columns='population_type', values='population_number')
df = df.reset_index()
#compute data for plotting
x = df['year']
y = df['Refugees']
#plot the chart
fig, ax = plt.subplots()
bar_plot = ax.plot(x, y)
#set chart title
ax.set_title('Number of refugees | 1990-2021')
#set y-axis label
ax.set_ylabel('Number of people (millions)')
#set y-axis limit
ylimit = plt.ylim(8 * 1e6, 22 * 1e6)
#format x-axis tick labels
def number_formatter(x, pos):
if x >= 1e6:
s = '{:1.0f}M'.format(x*1e-6)
elif x < 1e6 and x > 0:
s = '{:1.0f}K'.format(x*1e-3)
else:
s = '{:1.0f}'.format(x)
return s
ax.yaxis.set_major_formatter(number_formatter)
#set chart source and copyright
plt.annotate('Source: UNHCR Refugee Data Finder', (0,0), (0, -25), xycoords='axes fraction', textcoords='offset points', va='top', color = '#666666', fontsize=9)
plt.annotate('©UNHCR, The UN Refugee Agency', (0,0), (0, -35), xycoords='axes fraction', textcoords='offset points', va='top', color = '#666666', fontsize=9)
#adjust chart margin and layout
fig.tight_layout()
# Save the figure manually to the specified path
fig.savefig('plot/single-line.png')
#show chart
plt.show()
Multiple line chart
# import libraries
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
plt.style.use(['unhcrpyplotstyle','line'])
#compute data array for plotting
df = pd.read_csv('https://raw.githubusercontent.com/GDS-ODSSS/unhcr-dataviz-platform/master/data/change_over_time/line.csv')
df = df.pivot(index='year', columns='population_type', values='population_number')
df = df.reset_index()
#compute data for plotting
x = df['year']
y1 = df['IDPs']
y2 = df['Refugees']
#plot the chart
fig, ax = plt.subplots()
bar_plot = ax.plot(x, y1)
bar_plot = ax.plot(x, y2)
#set chart title
ax.set_title('Number of refugees and IDPs of concern to UNHCR | 1990-2021')
#set y-axis label
ax.set_ylabel('Number of people (millions)')
#set y-axis limit
ylimit = plt.ylim(0, 60 * 1e6)
#set direct labeling for lines
idp_xpos=x.iloc[-1]
idp_ypos=y1.iloc[-1]
plt.annotate("IDPs", (idp_xpos,idp_ypos),
textcoords="offset points",
xytext=(0,10),
ha='center')
ref_xpos=x.iloc[-1]
ref_ypos=y2.iloc[-1]
plt.annotate("Refugees", (ref_xpos,ref_ypos),
textcoords="offset points",
xytext=(0,10),
ha='left')
#format x-axis tick labels
def number_formatter(x, pos):
if x >= 1e6:
s = '{:1.0f}M'.format(x*1e-6)
elif x < 1e6 and x > 0:
s = '{:1.0f}K'.format(x*1e-3)
else:
s = '{:1.0f}'.format(x)
return s
ax.yaxis.set_major_formatter(number_formatter)
#set chart source and copyright
plt.annotate('Source: UNHCR Refugee Data Finder', (0,0), (0, -25), xycoords='axes fraction', textcoords='offset points', va='top', color = '#666666', fontsize=9)
plt.annotate('©UNHCR, The UN Refugee Agency', (0,0), (0, -35), xycoords='axes fraction', textcoords='offset points', va='top', color = '#666666', fontsize=9)
#adjust chart margin and layout
fig.tight_layout()
# Save the figure manually to the specified path
fig.savefig('plot/multiple-lines.png')
#show chart
plt.show()
Line column chart
A line column chart is a type of visualization that combines both line and column charts together, using dual axes displayed on the left and right sides of the chart. It allows us to show the relationship of two variables with different magnitudes and scales.
More about: Line column chart - Other tutorials: R D3
# import libraries
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
plt.style.use(['unhcrpyplotstyle','linecolumn'])
#compute data array for plotting
df = pd.read_csv('https://raw.githubusercontent.com/GDS-ODSSS/unhcr-dataviz-platform/master/data/change_over_time/line_column.csv')
#compute data for plotting
x = df['year']
y_col = df['displaced_population']
y_line = df['displaced_proportion']
#plot the bar
fig, ax1 = plt.subplots()
bar_plot=ax1.bar(x, y_col, label = 'Displaced population')
#set y axis limits
ylim1 = plt.ylim(0,100)
#plot the line that share the same x-axis with bar
ax2 = ax1.twinx()
line_plot=ax2.plot(x, y_line, color='#EF4A60', label = 'Porportion displaced')
#set y axis limits
ylim2 = plt.ylim(0,10)
#set x axis ticks
ax1.set_xticks(x)
#set chart title
ax1.set_title('Trend of global displacement | 2007 - 2016', pad=50)
#set chart legend
ax1.legend(loc=(0,1.05), ncol=1)
ax2.legend(loc=(0.3,1.05), ncol=1)
#set y-axis label
ax1.set_ylabel('Displaced population (millions)')
ax2.set_ylabel('Proportion displaced (number displaced per 1,000)')
#remove all ticks
ax1.tick_params(bottom=False,left=False)
ax2.tick_params(bottom=False, right=False)
#set chart source and copyright
plt.annotate('Source: UNHCR Refugee Data Finder', (0,0), (0, -25), xycoords='axes fraction', textcoords='offset points', va='top', color = '#666666', fontsize=9)
plt.annotate('©UNHCR, The UN Refugee Agency', (0,0), (0, -35), xycoords='axes fraction', textcoords='offset points', va='top', color = '#666666', fontsize=9)
#adjust chart margin and layout
fig.tight_layout()
# Save the figure to the specified path
fig.savefig('plot/line-column.png')
#show chart
plt.show()
Slope chart
A slope chart looks like a line chart, but unlike the line chart, it has only two data points for each line. The change between two data points can be easily identified with connected lines (slope up means increase, slope down means decrease).
More about: Slope chart - Other tutorials: R
# import libraries
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
plt.style.use(['unhcrpyplotstyle','slope'])
#load and reshape the data
df = pd.read_csv('https://raw.githubusercontent.com/GDS-ODSSS/unhcr-dataviz-platform/master/data/change_over_time/slope_2.csv')
#set a list of country names
countries=['Afghanistan','Dem. Rep. of the Congo','Myanmar','South Sudan','Syrian Arab Rep.']
#plot the chart
fig, ax = plt.subplots()
for i in countries:
temp = df[df['country_origin'] == i]
plt.plot(temp.year, temp.refugees_number, color='#0072BC', marker='o', markersize=5)
# start label
plt.text(temp.year.values[0]-0.4, temp.refugees_number.values[0], i, ha='right', va='center')
# end label
plt.text(temp.year.values[1]+0.4, temp.refugees_number.values[1], i, ha='left', va='center')
ticks = plt.xticks([2000, 2021])
xl = plt.xlim(1990,2031)
yl = plt.ylim(0, 7*1e6)
#set chart title
ax.set_title('Evolution of refugee population by country of origin |2000 vs 2021')
#set y-axis label
ax.set_ylabel('Number of people (millions)')
#format x-axis tick labels
def number_formatter(x, pos):
if x >= 1e6:
s = '{:1.0f}M'.format(x*1e-6)
elif x < 1e6 and x > 0:
s = '{:1.0f}K'.format(x*1e-3)
else:
s = '{:1.0f}'.format(x)
return s
ax.yaxis.set_major_formatter(number_formatter)
#set chart source and copyright
plt.annotate('Source: UNHCR Refugee Data Finder', (0,0), (0, -25), xycoords='axes fraction', textcoords='offset points', va='top', color = '#666666', fontsize=9)
plt.annotate('©UNHCR, The UN Refugee Agency', (0,0), (0, -35), xycoords='axes fraction', textcoords='offset points', va='top', color = '#666666', fontsize=9)
#adjust chart margin and layout
fig.tight_layout()
# Save the figure to the specified path
fig.savefig('plot/slope.png')
#show chart
plt.show()
Stacked area chart
As a variation of a simple area chart, a stacked area chart displays the changes of value of multiple data series over a period of time.
More about: Stacked area chart - Other tutorials: R D3
# import libraries
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
plt.style.use(['unhcrpyplotstyle','area'])
#load and reshape the data
df = pd.read_csv('https://raw.githubusercontent.com/GDS-ODSSS/unhcr-dataviz-platform/master/data/change_over_time/area_stacked.csv')
df = df.pivot_table(index='months', columns='funding_type', values='funding_million', sort=False)
df = df.reset_index()
#compute data for plotting
x = df['months']
y1 = df['Earmarked']
y2 = df['Softly earmarked']
y3 = df['Tightly earmarked']
y4 = df['Unearmarked']
#plot the chart
fig, ax = plt.subplots()
ax.stackplot(x, y1, y2, y3, y4, labels = ['Earmarked', 'Softly earmarked', 'Tightly earmarked', 'Unearmarked'])
#set chart legend
ax.legend(loc=(0,1.05), ncol=4)
#set chart title
ax.set_title('Evolution of funding in West Africa region | 2020', pad=50)
#set y-axis label
ax.set_ylabel('USD millions')
#set y-axis limit
yl = plt.ylim(0,500)
#set chart source and copyright
plt.annotate('Source: UNHCR Refugee Data Finder', (0,0), (0, -25), xycoords='axes fraction', textcoords='offset points', va='top', color = '#666666', fontsize=9)
plt.annotate('©UNHCR, The UN Refugee Agency', (0,0), (0, -35), xycoords='axes fraction', textcoords='offset points', va='top', color = '#666666', fontsize=9)
#adjust chart margin and layout
fig.tight_layout()
# Save the figure to the specified path
fig.savefig('plot/stacked-area.png')
#show chart
plt.show()
Streamgraph
A streamgraph is a variation of a stacked area chart. Instead of displaying values on top of a fixed, straight baseline at the bottom of the stack, the values of the streamgraph are displaced around a central baseline.
More about: Streamgraph - Other tutorials: R D3
# import libraries
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
plt.style.use(['unhcrpyplotstyle','streamgraph'])
#load and reshape the data
df = pd.read_csv('https://raw.githubusercontent.com/GDS-ODSSS/unhcr-dataviz-platform/master/data/change_over_time/streamgraph.csv')
df = df.pivot_table(index='year', columns='population_type', values='population_number')
df = df.reset_index()
df= df.fillna(0)
#compute data for plotting
x = df['year']
y1 = df['VDA']
y2 = df['OOC']
y3 = df['STA']
y4 = df['IDP']
y5 = df['ASY']
y6 = df['REF']
#plot the chart
fig, ax = plt.subplots()
ax.stackplot(x, y1, y2, y3, y4, y5, y6, colors = ['#EF4A60', '#999999', '#E1CC0D', '#00B398', '#18375F', '#0072BC'], labels = [ 'Venezuelans displaced abroad', 'Others of concern', 'Stateless persons', 'IDPs', 'Asylum-seekers', 'Refugees' ], baseline='weighted_wiggle')
#set chart title
ax.set_title('Evolution of people of concern to UNHCR | 1991-2020', pad=50)
#set chart legend
ax.legend(loc=(0,1), ncol=3)
#set y-axis label
ax.set_ylabel('Number of people (millions)')
#format y-axis tick labels
def number_formatter(x, pos):
if x >= 1e6:
s = '{:1.0f}M'.format(x*1e-6)
elif x < 1e6 and x > 0:
s = '{:1.0f}K'.format(x*1e-3)
elif x > -1e6 and x < 0:
s = '{:1.0f}K'.format(x*1e-3)
elif x <= -1e6:
s = '{:1.0f}M'.format(x*1e-6)
else:
s = '{:1.0f}'.format(x)
return s
ax.yaxis.set_major_formatter(number_formatter)
#set chart source and copyright
plt.annotate('Source: UNHCR Refugee Data Finder', (0,0), (0, -25), xycoords='axes fraction', textcoords='offset points', va='top', color = '#666666', fontsize=9)
plt.annotate('©UNHCR, The UN Refugee Agency', (0,0), (0, -35), xycoords='axes fraction', textcoords='offset points', va='top', color = '#666666', fontsize=9)
#adjust chart margin and layout
fig.tight_layout()
# Save the figure to the specified path
fig.savefig('plot/streamgraph.png')
#show chart
plt.show()