使用fig.add_axes添加双轴时触发AttributeError:'NoneType'无is_first_col属性
pandas.plot与fig.add_axes搭配触发AttributeError的根源分析
问题场景
使用pandas 1.5.3和matplotlib 3.7.1,通过fig.add_axes手动布局双坐标轴(拒绝依赖fig.add_subplot的自动布局)时,触发AttributeError: 'NoneType' object has no attribute 'is_first_col'。尝试过pandas#11520问题的colorbar=False解决方案,但无效。
示例代码:
import pandas as pd import numpy as np import matplotlib.pyplot as plt # 生成随机数据 df_1 = pd.DataFrame(np.random.randint(0,100,size=(1000, 1)), columns=list('v')) df_2 = pd.DataFrame(np.random.randint(0,100,size=(1000, 1)), columns=list('v')) # 创建基础画布 fig = plt.figure() # 添加第一个坐标轴 ax_1 = fig.add_axes([ 0.0, # 左侧位置 0.0, # 底部位置 0.5, # 宽度 1.0 # 高度 ]) df_1.plot(ax=ax_1) # 添加第二个坐标轴 ax_2 = fig.add_axes([0.5, 0.0, 0.5, 1.0]) df_2.plot(ax=ax_2)
报错堆栈:
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) Cell In[8], line 23 21 # 添加第二个坐标轴 22 ax_2 = fig.add_axes([0.5, 0.0, 0.5, 1.0]) ---> 23 df_2.plot(legend=False, ax=ax_2) File ~/dev/bdstb/.venv/lib/python3.10/site-packages/pandas/plotting/_core.py:1000, in PlotAccessor.__call__(self, *args, **kwargs) 997 label_name = label_kw or data.columns 998 data.columns = label_name -> 1000 return plot_backend.plot(data, kind=kind, **kwargs) File ~/dev/bdstb/.venv/lib/python3.10/site-packages/pandas/plotting/_matplotlib/__init__.py:71, in plot(data, kind, **kwargs) 69 kwargs["ax"] = getattr(ax, "left_ax", ax) 70 plot_obj = PLOT_CLASSES[kind](data, **kwargs) -> 71 plot_obj.generate() 72 plot_obj.draw() 73 return plot_obj.result File ~/dev/bdstb/.venv/lib/python3.10/site-packages/pandas/plotting/_matplotlib/core.py:455, in MPLPlot.generate(self) 453 self._add_table() 454 self._make_legend() -> 455 self._adorn_subplots() 457 for ax in self.axes: 458 self._post_plot_logic_common(ax, self.data) ... -> 400 is_first_col = lambda x: x.get_subplotspec().is_first_col() 401 else: 402 is_first_col = lambda x: x.is_first_col() AttributeError: 'NoneType' object has no attribute 'is_first_col'
核心根源
- pandas绘图模块的
_adorn_subplots方法会自动处理子图装饰(比如是否显示y轴标签),判断逻辑依赖坐标轴的子图规格(SubplotSpec)。 - 用
fig.add_axes创建的坐标轴是独立布局的,没有绑定SubplotSpec,调用get_subplotspec()会返回None,后续调用is_first_col()直接触发错误。 - 你提到的pandas#11520是针对带colorbar的绘图场景,和当前SubplotSpec缺失的问题无关,所以
colorbar=False的方案不起作用。
可行解决方案
方案一:跳过pandas的子图装饰逻辑
调用df.plot()时指定sharex=False和sharey=False,强制pandas不执行子图网格相关的判断:
df_1.plot(ax=ax_1, sharex=False, sharey=False) df_2.plot(ax=ax_2, sharex=False, sharey=False)
方案二:直接使用matplotlib绘图
绕开pandas的绘图封装,直接用matplotlib的原生方法绘制,完全避免pandas的自动装饰逻辑:
# 替代df.plot的写法 ax_1.plot(df_1['v']) ax_2.plot(df_2['v'])
内容的提问来源于stack exchange,提问作者Basti Tee
相关产品推荐
相关产品推荐

