Matplotlib极坐标绘制环形区域浓度常数异常问题
极坐标下扩散浓度绘图异常问题
问题背景
用欧拉显式方法计算极坐标下的简单非稳态扩散,r范围为1到10,步长dr=0.5。由于无平流作用,浓度仅随r变化(即C(r,t)),需要绘制极坐标图。
计算得到的最终结果
r = [ 1. 1.5 2. 2.5 3. 3.5 4. 4.5 5. 5.5 6. 6.5 7. 7.5 8. 8.5 9. 9.5 10. ] C = [3.0, 2.9999999999971694, 2.999999999995282, 2.9999999999940608, 2.9999999999932836, 2.9999999999928395, 2.9999999999926175, 2.9999999999925064, 2.9999999999926175, 2.9999999999928395, 2.9999999999931726, 2.9999999999937277, 2.999999999994394, 2.999999999995171, 2.999999999995948, 2.9999999999969473, 2.9999999999979465, 2.9999999999989457, 3.0]
当前绘图代码
theta = np.linspace(0, 2 * np.pi, 360) # Generate theta values R, Theta = np.meshgrid(r, theta) conc = np.array([C]*len(theta)).transpose() # C is constant over theta fig, ax = plt.subplots(subplot_kw=dict(projection='polar')) ax.contourf(theta, r, conc) plt.show()
异常现象
绘图结果异常:浓度显示范围仅为r=0到≈3.5,以及≈5.5到10,但实际计算的r范围是1到10,每个r都对应有效浓度值。
问题原因与解决方法
核心原因
你的浓度值变化极小(仅在3附近波动,差值约为1e-12量级),而contourf默认的自动分层逻辑无法识别这么细微的差异,导致部分区域的浓度被归为同一层级,出现视觉上的“断层”。
解决方案1:手动设置分层级别
手动生成足够多的分层区间,让绘图能捕捉到微小的浓度变化:
import numpy as np import matplotlib.pyplot as plt r = np.array([1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 9.0, 9.5, 10.0]) C = np.array([3.0, 2.9999999999971694, 2.999999999995282, 2.9999999999940608, 2.9999999999932836, 2.9999999999928395, 2.9999999999926175, 2.9999999999925064, 2.9999999999926175, 2.9999999999928395, 2.9999999999931726, 2.9999999999937277, 2.999999999994394, 2.999999999995171, 2.999999999995948, 2.9999999999969473, 2.9999999999979465, 2.9999999999989457, 3.0]) theta = np.linspace(0, 2 * np.pi, 360) conc = np.tile(C, (len(theta), 1)).T # 等价于你的transpose写法,更简洁 fig, ax = plt.subplots(subplot_kw=dict(projection='polar')) # 手动生成分层,覆盖浓度的最小到最大值,生成20个层级 levels = np.linspace(C.min(), C.max(), 20) ax.contourf(theta, r, conc, levels=levels) # 添加颜色条查看浓度对应关系 plt.colorbar() plt.show()
解决方案2:改用pcolormesh绘图
pcolormesh更适合处理这种网格规则、数值变化细微的场景,不需要手动设置分层:
import numpy as np import matplotlib.pyplot as plt r = np.array([1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 9.0, 9.5, 10.0]) C = np.array([3.0, 2.9999999999971694, 2.999999999995282, 2.9999999999940608, 2.9999999999932836, 2.9999999999928395, 2.9999999999926175, 2.9999999999925064, 2.9999999999926175, 2.9999999999928395, 2.9999999999931726, 2.9999999999937277, 2.999999999994394, 2.999999999995171, 2.999999999995948, 2.9999999999969473, 2.9999999999979465, 2.9999999999989457, 3.0]) theta = np.linspace(0, 2 * np.pi, 360) # 生成极坐标网格 R, Theta = np.meshgrid(r, theta) # 扩展C到theta维度 conc = np.tile(C, (len(theta), 1)) fig, ax = plt.subplots(subplot_kw=dict(projection='polar')) ax.pcolormesh(Theta, R, conc) plt.colorbar() plt.show()
额外优化
如果想隐藏r=0到1之间的空白区域,可以设置坐标轴的r范围:
ax.set_ylim(bottom=1)
内容的提问来源于stack exchange,提问作者aleste
相关产品推荐
相关产品推荐

