You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Matplotlib图表轴左侧添加轴截断波浪线?

为Matplotlib哑铃图添加Y轴截断波浪线

问题描述

我想要复刻《经济学人》风格的哑铃图,已通过Matplotlib实现基础效果,但生成的图表缺少Y轴左侧代表轴截断部分的波浪线,需要添加该效果。

解决方案

可以利用Matplotlib的Path和PathPatch类绘制自定义波浪线,将其添加到Y轴对应位置即可。具体步骤如下:

  • 导入绘制自定义路径所需的模块
  • 定义波浪线的路径坐标,通过轴坐标定位到Y轴左侧
  • 创建路径补丁并添加到图表轴上

修改后的完整代码

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.path import Path
from matplotlib.patches import PathPatch

# 提高图表分辨率
plt.rcParams['figure.dpi'] = 100

# 导入数据
gdp = pd.read_csv('gdp_1960_2020.csv')
# 预先定义要展示的国家列表
countries = ['United States', 'China', 'Japan', 'Germany', 'India', 'United Kingdom', 'France', 'Italy', 'Brazil']

# 处理数据
gdp_dumbbell = (gdp[(gdp['country'].isin(countries)) & ((gdp['year'] == 2000) | (gdp['year'] == 2020))][['year','gdp_trillions','country']]
            .pivot(index='country',columns='year', values='gdp_trillions')
            .sort_values(by=2020))

# 设置图表尺寸
fig, ax = plt.subplots(figsize=(7,4))

# 创建网格(置于数据下方)
ax.grid(which="major", axis='both', color='#758D99', alpha=0.6, zorder=1)

# 隐藏部分边框
ax.spines[['top','right','bottom']].set_visible(False)

# 绘制哑铃图的水平线和散点
ax.hlines(y=gdp_dumbbell.index, xmin=gdp_dumbbell[2000], xmax=gdp_dumbbell[2020], color='#758D99', zorder=2, linewidth=2, label='_nolegend_', alpha=.8)
ax.scatter(gdp_dumbbell[2000], gdp_dumbbell.index, label='2000', s=60, color='#DB444B', zorder=3)
ax.scatter(gdp_dumbbell[2020], gdp_dumbbell.index, label='2020', s=60, color='#006BA2', zorder=3)

# 设置X轴范围
ax.set_xlim(0, 25.05)

# 格式化X轴刻度
ax.xaxis.set_tick_params(labeltop=True, labelbottom=False, bottom=False, labelsize=11, pad=-1)

# 格式化Y轴刻度
ax.set_yticklabels(gdp_dumbbell.index, ha='left')
ax.yaxis.set_tick_params(pad=100, labelsize=11, bottom=False)

# 添加Y轴底部截断波浪线
# 用轴坐标定义路径:x=-0.03表示Y轴左侧3%的轴宽度位置
wave_x = [-0.03, -0.03, -0.02, -0.04, -0.02, -0.04, -0.03]
wave_y = [0.02, 0.08, 0.05, 0.07, 0.03, 0.05, 0.02]
path = Path([(x, y) for x, y in zip(wave_x, wave_y)], 
            [Path.MOVETO, Path.CURVE4, Path.CURVE4, Path.CURVE4,
             Path.CURVE4, Path.CURVE4, Path.CLOSEPOLY])
patch = PathPatch(path, facecolor='none', edgecolor='#758D99', linewidth=1.5, transform=ax.transAxes)
ax.add_patch(patch)

# 可选:添加Y轴顶部截断波浪线
# wave_y_top = [0.92, 0.98, 0.95, 0.97, 0.93, 0.95, 0.92]
# path_top = Path([(x, y) for x, y in zip(wave_x, wave_y_top)], 
#             [Path.MOVETO, Path.CURVE4, Path.CURVE4, Path.CURVE4,
#              Path.CURVE4, Path.CURVE4, Path.CLOSEPOLY])
# patch_top = PathPatch(path_top, facecolor='none', edgecolor='#758D99', linewidth=1.5, transform=ax.transAxes)
# ax.add_patch(patch_top)

# 设置图例
ax.legend(['2000', '2020'], loc=(-.29,1.09), ncol=2, frameon=False, handletextpad=-.1, handleheight=1)

# 添加标题栏装饰
ax.plot([-0.08, .9], [1.17, 1.17], transform=fig.transFigure, clip_on=False, color='#E3120B', linewidth=.6)
ax.add_patch(plt.Rectangle((-0.08,1.17), 0.05, -0.025, facecolor='#E3120B', transform=fig.transFigure, clip_on=False, linewidth=0))

# 添加标题和副标题
ax.text(x=-0.08, y=1.09, s="Great expectations", transform=fig.transFigure, ha='left', fontsize=13, weight='bold', alpha=.8)
ax.text(x=-0.08, y=1.04, s="Top 9 countries by GDP, in trillions of USD", transform=fig.transFigure, ha='left', fontsize=11, alpha=.8)

# 添加来源信息
ax.text(x=-0.08, y=0.04, s="""Source: "GDP of all countries(1960-2020)" via Kaggle.com""", transform=fig.transFigure, ha='left', fontsize=9, alpha=.7)

plt.show()

说明

  • 波浪线通过轴坐标定位,ax.transAxes表示坐标范围为0到1,对应轴的宽高比例,方便自适应图表尺寸
  • 可调整wave_x和wave_y的数值改变波浪线的大小、位置和弯曲程度
  • 若需要在Y轴顶部添加截断效果,取消注释对应代码块即可

内容的提问来源于stack exchange,提问作者L Robinson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 06:44:55