import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from scipy.interpolate import make_interp_spline
from PIL import Image
import matplotlib.cm as cm
以下数据如果有需要的同学可关注公众号HsuHeinrich,回复【数据可视化】自动获取~
# 导入数据
url = "https://raw.githubusercontent.com/holtzy/R-graph-gallery/master/DATA/wealth_data.xlsx"
df = pd.read_excel(url)
df.head()

image-20240129182457555
pivot_df = df.pivot(index='year', columns='country', values='total_wealth')
# 数据透视
pivot_df = df.pivot(index='year', columns='country', values='total_wealth')
# 初始化布局
plt.figure(figsize=(6, 6))
# 绘制堆叠面积图
plt.stackplot(pivot_df.index,
pivot_df.values.T,
labels=pivot_df.columns)
plt.xlabel('Year')
plt.ylabel('Total Wealth')
plt.title('A Simple Stacked Area Chart')
plt.legend(loc='upper left')
plt.show()

output_7_0
# 数据透视
pivot_df = df.pivot(index='year', columns='country', values='total_wealth')
# 自定义颜色列表
custom_colors = ["#003f5c","#2f4b7c","#665191","#a05195","#d45087","#f95d6a","#ff7c43","#ffa600"]
# 使用样条插值平滑线条
x_smooth = np.linspace(pivot_df.index.min(), pivot_df.index.max(), 300)
pivot_smooth = pd.DataFrame({country: make_interp_spline(pivot_df.index, pivot_df[country])(x_smooth)
for country in pivot_df.columns})
# 布局
plt.figure(figsize=(6, 6))
# 绘制堆叠面积图
plt.stackplot(x_smooth,
pivot_smooth.values.T,
labels=pivot_smooth.columns,
colors=custom_colors)
plt.xlabel('Year')
plt.ylabel('Total Wealth')
plt.title('Stacked Area Chart with Smoothing and Customized Colors')
plt.legend(loc='upper left')
plt.show()

output_9_0
# 数据透视
pivot_df = df.pivot(index='year', columns='country', values='total_wealth')
# 自定义颜色列表
custom_colors = ["#003f5c","#2f4b7c","#665191","#a05195","#d45087","#f95d6a","#ff7c43","#ffa600"]
# 自定义顺序
desired_order = ["United States", "China", "Japan", "Germany", "United Kingdom", "France", "India", "Other"]
pivot_df = pivot_df[desired_order]
# 使用样本插值平滑线条
x_smooth = np.linspace(pivot_df.index.min(), pivot_df.index.max(), 300)
pivot_smooth = pd.DataFrame({country: make_interp_spline(pivot_df.index, pivot_df[country])(x_smooth)
for country in pivot_df.columns})
# 布局
plt.figure(figsize=(6, 6))
# 绘制堆叠面积图
plt.stackplot(x_smooth,
pivot_smooth.values.T,
labels=pivot_smooth.columns,
colors=custom_colors)
plt.xlabel('Year')
plt.ylabel('Total Wealth')
plt.title('Stacked Area Chart with Smoothing and Customized Colors')
plt.legend(loc='upper left')
plt.show()

output_11_0
# 数据透视
pivot_df = df.pivot(index='year', columns='country', values='total_wealth')
# 自定义颜色列表
custom_colors = ["#003f5c","#2f4b7c","#665191","#a05195","#d45087","#f95d6a","#ff7c43","#ffa600"]
# 自定义排序
desired_order = ["United States", "China", "Japan", "Germany", "United Kingdom", "France", "India", "Other"]
pivot_df = pivot_df[desired_order]
# 使用样本插值平滑线条
x_smooth = np.linspace(pivot_df.index.min(), pivot_df.index.max(), 300)
pivot_smooth = pd.DataFrame({country: make_interp_spline(pivot_df.index, pivot_df[country])(x_smooth)
for country in pivot_df.columns})
# 布局
plt.figure(figsize=(8, 8))
# 绘制堆叠面积图
plt.stackplot(x_smooth, pivot_smooth.values.T, labels=pivot_smooth.columns, colors=custom_colors)
# 获取当前轴
ax = plt.gca()
# 自定义函数注释每年数据
def add_annotations_year(year):
"""
year: 年份
结果:每年绘制一条直线,顶部记录当年的财富总额
"""
# 计算财富总额
y_end = df[df["year"]==year]["total_wealth"].sum()
# 自定义位置
if year==2021:
modif_xaxis = -3.3
modif_yaxis = 20000
else:
modif_xaxis = -1.5
modif_yaxis = 26000
# 添加文本
plt.text(year+modif_xaxis,
y_end+modif_yaxis,
f'${y_end}M',
fontsize=10,
color='black',
fontweight = 'bold')
# 添加线(两个点的直线)
ax.plot([year, year],
[0, y_end*1.05],
color='black',
linewidth=1)
# 添加点(位于线顶端)
ax.plot(year,
y_end*1.05,
marker='o',
markersize=5,
color='black')
# 指定年份调用add_annotations_year函数
for year in [2000,2005,2010,2015,2021]:
add_annotations_year(year)
# 自定义函数注释每个国家/地区数据
def add_annotations_country(country, value_placement, amount, color):
"""
在指定位置注释每个国家的名称、颜色、财富总额
"""
plt.text(2021.5, value_placement, f'{country} ${amount}M', fontsize=10, color=color, fontweight='bold')
# 自定义参数值country、value_placement、amount、color
countries = ['Rest of the world', 'India', 'France', 'UK', 'Germany', 'Japan', 'China', 'USA']
values_placement = [400000, 310000, 295000, 275000, 260000, 240000, 180000, 70000]
amounts = [142841, 14225, 16159, 16261, 17489, 25692, 85107, 145793]
custom_colors.reverse() # 保证颜色与国家面积图颜色一致
# 遍历国家增加注释
for country, value, amount, color in zip(countries, values_placement, amounts, custom_colors):
add_annotations_country(country, value, amount, color)
# 标题
plt.text(2000, 320000,
'Aggregated \nHousehold \nWealth',
fontsize=40,
color='black',
fontweight = 'bold')
# 著作信息
plt.text(2000, -50000, 'Data:', fontsize=8, color='black', fontweight = 'bold')
plt.text(2001.4, -50000, 'James Davies, Rodrigo Lluberas and Anthony Shorrocks, Credit Suisse Global Wealth Databook 2022', fontsize=8, color='black')
plt.text(2000, -63000, 'Design:', fontsize=8, color='black', fontweight = 'bold')
plt.text(2001.9, -63000, 'Gilbert Fontana', fontsize=8, color='black')
# 移除部分边框
ax.spines['left'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
# 删除刻度和标签
ax.tick_params(left=False, labelleft=False)
plt.show()

output_13_0
参考:Stacked line chart with inline labels[1]
共勉~
[1]
Stacked line chart with inline labels: https://python-graph-gallery.com/web-stacked-line-chart-with-labels/