如何在Matplotlib中绘制带圆角的极坐标柱状图?
纯Matplotlib实现极坐标柱状图圆角的方案
普通的Matplotlib极坐标柱状图(plt.bar(polar=True))不支持直接设置圆角,不过可以通过自定义路径(Path)来实现,这是最简便的纯Matplotlib原生方法,不需要额外依赖。
核心思路
极坐标下的圆角柱状图,本质是把每个柱的外边缘两个直角替换成圆弧。我们可以通过Path对象手动构建包含圆弧的柱形路径,再用PathPatch添加到极轴上。
实现代码
import matplotlib.pyplot as plt from matplotlib.path import Path import matplotlib.patches as patches import numpy as np def add_rounded_polar_bar(theta, bar_width, bar_height, corner_radius, ax): # 转换角度为弧度 theta_rad = np.radians(theta) width_rad = np.radians(bar_width) # 极坐标转笛卡尔坐标的工具函数 def polar2cart(r, angle): return (r * np.cos(angle), r * np.sin(angle)) # 柱形的关键顶点坐标(极坐标转笛卡尔) inner_left = polar2cart(0, theta_rad) inner_right = polar2cart(0, theta_rad + width_rad) outer_left = polar2cart(bar_height - corner_radius, theta_rad) outer_right = polar2cart(bar_height - corner_radius, theta_rad + width_rad) # 构造路径的顶点和指令码 vertices = [inner_left, outer_left] codes = [Path.MOVETO, Path.LINETO] # 添加外边缘的圆角圆弧 arc_center = polar2cart(bar_height, theta_rad + width_rad/2) # 创建圆弧路径,缩放平移到对应位置 arc = Path.arc(np.degrees(theta_rad), np.degrees(theta_rad + width_rad)) arc = arc.transformed( plt.matplotlib.transforms.Affine2D().scale(corner_radius).translate(*arc_center) ) vertices.extend(arc.vertices) codes.extend(arc.codes) # 完成柱形路径的剩余部分 vertices.extend([outer_right, inner_right]) codes.extend([Path.LINETO, Path.LINETO]) codes.append(Path.CLOSEPOLY) # 创建补丁并添加到轴上 path = Path(vertices, codes) patch = patches.PathPatch(path, facecolor='#1f77b4', edgecolor='black', linewidth=1) ax.add_patch(patch) return patch # 示例使用 fig, ax = plt.subplots(subplot_kw={'polar': True}, figsize=(8,8)) # 测试数据 angles = np.arange(0, 360, 45) bar_widths = [30]*8 heights = [2, 3, 4, 3, 2, 1, 2, 3] corner_r = 0.4 for angle, h in zip(angles, heights): add_rounded_polar_bar(angle, bar_widths[0], h, corner_r, ax) # 调整极轴范围和样式 ax.set_ylim(0, max(heights) + 0.5) ax.set_yticks([]) plt.show()
说明
- 这个方法通过
Path.arc生成圆角圆弧,再通过仿射变换平移缩放到柱形的外边缘位置,比手动生成圆弧点更高效。 - 你可以通过调整
corner_radius参数控制圆角的大小,数值越大圆角越明显(注意不要超过柱形宽度的一半)。 - 可以自由修改
facecolor、edgecolor等样式参数,匹配你需要的视觉效果。
内容的提问来源于stack exchange,提问作者ruthpozuelo
相关产品推荐
相关产品推荐

