调用Seaborn的sns.categorical._CountPlotter触发TypeError错误的排查求助
出现这个TypeError: ufunc 'true_divide' not supported...的核心原因是你直接调用了Seaborn的内部私有类_CountPlotter,而它的默认参数是为连续数据的条形图(比如barplot)设计的,并不适配countplot的计数逻辑。
具体原因拆解
countplot本质是barplot的封装,它底层会对数据做特殊处理:
- 自动生成一个全1的
y数组(用来统计每组的数量) - 将
estimator设置为len(统计每组的样本数)
而你直接调用_CountPlotter时,用了默认的estimator=np.mean(计算均值)和y=None,这会导致代码试图对x="class"这类字符串型类别数据计算均值,自然触发类型不兼容的除法错误。
排查与解决步骤
对齐Seaborn countplot的内部参数设置
模仿seaborn.countplot的源码逻辑,修改你调用_CountPlotter的参数:import numpy as np import seaborn as sns import matplotlib.pyplot as plt from seaborn.categorical import _CountPlotter titanic = sns.load_dataset("titanic") # 关键修改:设置y为全1数组,estimator为len plotter = _CountPlotter( data=titanic, x='class', y=np.ones(len(titanic)), # 模拟countplot的y参数处理 hue='who', estimator=len, # 替换为计数用的estimator ci=None, # 计数不需要置信区间,禁用避免无效计算 n_boot=0, order=None, hue_order=None, units=None, seed=None, orient=None, color=None, palette=None, saturation=.75, errcolor=".26", errwidth=None, capsize=None, dodge=True ) # 测试是否能正常绘制 plotter.draw() plt.show()这样修改后,应该能成功初始化
_CountPlotter并生成图表。参考Seaborn官方源码确认参数逻辑
你可以查看seaborn/categorical.py中countplot的实现,它内部调用_CountPlotter时做了这些关键处理:# 摘自Seaborn countplot源码 def countplot(..., **kwargs): # ... 省略其他代码 plotter = _CountPlotter( x=x, y=y, hue=hue, data=data, order=order, hue_order=hue_order, estimator=len, ci=None, n_boot=0, units=units, seed=seed, orient=orient, color=color, palette=palette, saturation=saturation, errcolor=errcolor, errwidth=errwidth, capsize=capsize, dodge=dodge ) # ...官方特意设置了
ci=None和n_boot=0,因为计数场景不需要置信区间计算,这也能避免不必要的计算错误。适配statannotations的扩展需求
当你给statannotations添加countplot支持时,需要在代码中:- 检测到是countplot时,自动设置
estimator=len、y=np.ones(len(data))(或类似处理) - 禁用置信区间相关参数(比如
ci=None),避免无效计算 - 确保后续的卡方检验逻辑能正确获取每组的计数数据(可以从
plotter对象中提取统计后的数值)
- 检测到是countplot时,自动设置
总结
核心问题就是私有类_CountPlotter的默认参数不匹配countplot的计数场景,只要对齐Seaborn官方countplot的参数设置,就能解决这个类型错误。后续扩展statannotations时,也要遵循这个参数适配逻辑,才能顺利集成卡方检验功能。
内容的提问来源于stack exchange,提问作者Christopher Creveling

