风玫瑰图中zorder属性失效,网格线覆盖柱状图问题求助
问题描述

我已为柱状图设置了比网格线更高的zorder值,但网格线仍显示在柱状图上方。我还尝试使用了ax.set_axisbelow(True),但也不起作用。能否有人解释如何解决该问题?
from windrose import WindroseAxes import pandas as pd import matplotlib.pyplot as plt # 示例数据 data = { 'WD (Deg)': [45, 90, 135, 180, 225, 270, 315, 0, 45], 'WS (m/s)': [2, 3, 4, 5, 6, 7, 8, 9, 10]} # 创建DataFrame df = pd.DataFrame(data) # 创建WindroseAxes对象 ax = WindroseAxes.from_ax() # 自定义网格 ax.grid(True, linestyle='--', linewidth=2.0, alpha=0.5, color='grey', zorder = 0) # 设置坐标轴在风玫瑰柱状图下方 ax.set_axisbelow(True) ## 不起作用 # 绘制风玫瑰柱状图 ax.bar(df['WD (Deg)'], df['WS (m/s)'], normed=True, opening=0.5, edgecolor='black', cmap=plt.cm.jet, zorder = 3) plt.show()
我不清楚这是为什么。我希望将网格线绘制在柱状图下方。提前感谢!
解决方案
问题出在windrose库的WindroseAxes.bar()方法上——它默认会把绘制的柱状图元素添加到ax.patch层级的下方,而网格线的渲染逻辑和普通matplotlib轴不同,直接设置zorder或set_axisbelow(True)不会生效。
你可以通过以下两种方式解决:
方法一:手动调整柱状图元素的zorder
先绘制柱状图,再设置网格,之后遍历所有柱状图补丁,修改它们的zorder值:
from windrose import WindroseAxes import pandas as pd import matplotlib.pyplot as plt # 示例数据 data = { 'WD (Deg)': [45, 90, 135, 180, 225, 270, 315, 0, 45], 'WS (m/s)': [2, 3, 4, 5, 6, 7, 8, 9, 10]} df = pd.DataFrame(data) ax = WindroseAxes.from_ax() # 先绘制柱状图 bars = ax.bar(df['WD (Deg)'], df['WS (m/s)'], normed=True, opening=0.5, edgecolor='black', cmap=plt.cm.jet) # 遍历所有柱状图元素,设置更高的zorder for bar in bars: bar.set_zorder(3) # 自定义网格,设置更低的zorder ax.grid(True, linestyle='--', linewidth=2.0, alpha=0.5, color='grey', zorder=0) plt.show()
方法二:将网格线移到最底层
直接把网格线的zorder设为负数,确保它在所有绘图元素的下方:
from windrose import WindroseAxes import pandas as pd import matplotlib.pyplot as plt # 示例数据 data = { 'WD (Deg)': [45, 90, 135, 180, 225, 270, 315, 0, 45], 'WS (m/s)': [2, 3, 4, 5, 6, 7, 8, 9, 10]} df = pd.DataFrame(data) ax = WindroseAxes.from_ax() # 自定义网格 ax.grid(True, linestyle='--', linewidth=2.0, alpha=0.5, color='grey') # 将网格线的zorder设为负数,放在最底层 ax.gridlines.set_zorder(-1) # 绘制柱状图 ax.bar(df['WD (Deg)'], df['WS (m/s)'], normed=True, opening=0.5, edgecolor='black', cmap=plt.cm.jet) plt.show()
核心原因
WindroseAxes是matplotlib轴的自定义子类,它的元素渲染顺序和普通Axes有差异,bar()方法内部不会直接响应你传入的zorder参数,必须手动调整已生成元素的层级,或者把网格线强制放到最底层。
内容的提问来源于stack exchange,提问作者Arindam Das
相关产品推荐
相关产品推荐

