matplotlib fill_between填充极坐标曲线公共区域出现倒置问题
问题原因
填充异常和fill_between的where参数无关,核心是极径负值的处理逻辑错误:
- 圆方程
r1 = sqrt(3)*sin(φ)的有效非负极径仅在φ ∈ [0, π]区间存在,当φ ∈ (π, 2π)时sin(φ)为负,计算得到的r1为负值。极坐标规则下负r值对应沿当前角度反方向取点,这部分轨迹实际和[0, π]区间的圆轨迹重合,圆本身完全分布在极轴上方,底部(π,2π)区间没有属于圆的正向区域。 - 心形线方程
r2 = 1 - cos(φ)的r值恒大于等于0,直接用np.minimum(r1, r2)取最小值时,(π,2π)区间的r3会取到负值的r1,fill_between填充从0到负r的区域时,就会沿角度反方向延伸,出现底部填充倒置的问题。
排查方向
- 先校验所有极径函数的取值范围,极坐标绘图/填充时优先过滤极径为负的无效值,除非明确需要负r的映射效果
- 极坐标下
fill_between的填充逻辑严格按照传入的r数值沿径向延伸,r为负时填充方向会从原点指向当前角度的反方向,不要默认传入的r值会自动做非负截断
修复代码
将r1的负值部分直接置0(对应区域不属于圆的覆盖范围,自然不会出现在公共区域内)即可得到正确填充效果:
import matplotlib.pyplot as plt import numpy as np import math phi = np.arange(0, 2 * np.pi, 0.01) r1 = math.sqrt(3) * np.sin(phi) # 截断负极径,排除圆不存在的底部区间 r1[r1 < 0] = 0 r2 = 1 - np.cos(phi) r3 = np.minimum(r1, r2) plt.polar(phi, r1) plt.polar(phi, r2) plt.fill_between(phi, 0, r3, color='#D0D0FF') plt.show()
如果需要更严谨的分段实现,可以先求解两曲线交点:两线交于φ=0(原点)和φ=π/3位置,[0, π/3]区间公共边界取r1,[π/3, π]区间公共边界取r2,(π, 2π)区间无公共区域,最终填充效果和上述截断负r的方案完全一致。
内容的提问来源于stack exchange,提问作者Dmitry Nosachev
相关产品推荐
相关产品推荐

