如何在Matplotlib中优化径向龙卷风图的极坐标轴重叠与标签定位?
解决Matplotlib径向龙卷风图的两个布局与标签问题
问题1:让两个极坐标子图紧密重叠且保留圆弧圆角
极坐标子图的布局逻辑和笛卡尔坐标不同,tight_layout或普通wspace设置效果有限,可通过以下方式解决:
- 移除
fig.tight_layout(h_pad=-40),改用fig.subplots_adjust设置负wspace,强制两个子图向中间靠拢; - 不用
set_thetamax(180),而是给theta最大值预留5度余量,避免圆角被截断,同时统一两个子图的极坐标参数保证视觉一致; - 通过
set_thetamin/-max限制显示范围,既保留圆角又确保子图对称。
问题2:自动定位标签,避免硬编码偏移
国家名称(径向标签)
无需使用固定的figure坐标系坐标,直接在画布中间垂直区域添加一次标签,按径向层级等距分布,避免重复绘制。
数值标签(圆弧末端)
因linewidth较宽且用了round端点样式,需微调r值让文字向外偏移,同时根据子图方向调整theta位置,确保文字落在圆弧外侧中心,适配不同长度的圆弧。
修改后的完整代码
import matplotlib.pyplot as plt import numpy as np import pandas as pd color_dict = {"Denmark": "#A54836", "Norway": "#2B314D", "Sweden": "#5375D4"} data = { "year": [2004, 2022, 2004, 2022, 2004, 2022], "countries": ["Sweden", "Sweden", "Denmark", "Denmark", "Norway", "Norway"], "sites": [13, 15, 4, 10, 5, 8] } df = pd.DataFrame(data) df['sub_total'] = df.groupby('year')['sites'].transform('sum') df = df.sort_values(['countries', 'sites'], ascending=True).reset_index(drop=True) # 创建极坐标子图,手动控制布局 fig, axes = plt.subplots(ncols=2, figsize=(10, 5), facecolor="#FFFFFF", subplot_kw=dict(polar=True)) # 设置负wspace让子图紧密重叠,调整边距避免内容溢出 fig.subplots_adjust(wspace=-0.4, left=0.1, right=0.9) countries = df.countries.unique() years = df.year.unique() directions = [1, -1] radius_levels = np.arange(1, len(countries)+1) # 每个国家的径向层级 # 一次性添加中间的国家名称标签 for i, country in enumerate(countries): fig.text(0.5, 0.5 + (i - 1)*0.1, country, ha="center", va="center", fontsize=12) for ax, year, direction in zip(axes.ravel(), years, directions): temp_df = df[df.year == year] for i, (country, site) in enumerate(zip(temp_df.countries, temp_df.sites)): r = radius_levels[i] # 计算theta范围,预留圆角空间 angle_range = np.linspace(0, site * 7) theta = np.deg2rad(angle_range if direction ==1 else -angle_range) ax.plot(theta, np.full(len(theta), r), linewidth=15, solid_capstyle="round", color=color_dict[country]) # 自动定位数值标签:偏移r值+微调theta,避免被圆角遮挡 label_r = r + 0.15 label_theta = theta[-1] + np.deg2rad(2)*direction ax.annotate(site, xy=(label_theta, label_r), color="w", ha="center", va="center", fontsize=10) # 统一极坐标配置 ax.set_rmax(max(radius_levels) + 0.5) ax.set_theta_zero_location('N') ax.set_theta_direction(direction) ax.set_thetamin(-95) ax.set_thetamax(95) ax.grid(False) ax.axis('off') plt.show()
关键修改说明
- 子图重叠:
fig.subplots_adjust(wspace=-0.4)强制子图向中间挤压,left/right参数控制整体边距,防止内容溢出画布; - 圆角保留:theta计算时预留余量,配合
set_thetamin/-max限制显示范围,既保证子图对称又不截断圆弧圆角; - 国家标签:在画布中间垂直区域按径向层级等距分布,仅绘制一次,无需硬编码偏移值;
- 数值标签:通过偏移r值和微调theta,让文字自动适配圆弧长度,始终落在外侧中心位置。
内容的提问来源于stack exchange,提问作者ruthpozuelo
相关产品推荐
相关产品推荐

