如何在Seaborn jointplot中同时使用hue参数与密度直方图?
问题:Seaborn jointplot同时设置hue和密度型边缘直方图报错
我需要在Seaborn的jointplot中实现两个效果:
- 通过
hue参数按数据集的类别变量区分颜色 - 边缘直方图以
stat='density'(密度)而非绝对值绘制(某类别样本量远大于另一类,用计数展示会失衡)
但同时设置这两个参数时触发报错,示例代码及错误信息如下:
示例代码
penguins=sns.load_dataset('penguins') sns.jointplot(data=penguins, x="bill_length_mm", y="bill_depth_mm", hue='species',marginal_kws=dict(color='r',stat='density'))
错误信息
AttributeError Traceback (most recent call last) <ipython-input-15-e8d515eeeab0> in <module> ----> 1 sns.jointplot(data=penguins, x="bill_length_mm", y="bill_depth_mm", hue='species',marginal_kws=dict(color='r',stat='density')) 12 frames /usr/local/lib/python3.8/dist-packages/matplotlib/artist.py in _update_property(self, k, v) 999 func = getattr(self, 'set_' + k, None) 1000 if not callable(func): -> 1001 raise AttributeError('{!r} object has no property {!r}' 1002 .format(type(self).__name__, k)) 1003 return func(v) AttributeError: 'PolyCollection' object has no property 'stat'
问题原因
当使用hue参数时,jointplot的边缘图会生成分层可视化(对应Seaborn底层的histplot分层模式),此时marginal_kws中的参数会被传递给所有底层绘图元素。stat是histplot的专属参数,但分层绘制时生成的PolyCollection对象不支持该属性,因此触发报错。另外,手动设置color='r'会覆盖hue的颜色区分,违背需求。
解决方法
方法一:正确传递边缘图参数
保留hue的同时,在marginal_kws中传递stat='density',并且不设置固定颜色,同时开启marginal_ticks让密度刻度正常显示:
import seaborn as sns penguins = sns.load_dataset('penguins') sns.jointplot( data=penguins, x="bill_length_mm", y="bill_depth_mm", hue='species', marginal_ticks=True, marginal_kws=dict(stat='density', multiple='layer') )
stat='density':将边缘直方图从计数切换为密度计算multiple='layer':保持分层直方图的叠加显示(可根据需求改为'dodge'并列或'fill'填充)
方法二:手动修改边缘轴
如果需要更灵活的定制,可以先绘制基础jointplot,再手动获取边缘轴修改直方图属性:
import seaborn as sns penguins = sns.load_dataset('penguins') g = sns.jointplot( data=penguins, x="bill_length_mm", y="bill_depth_mm", hue='species' ) # 清空默认边缘图 g.ax_marg_x.clear() g.ax_marg_y.clear() # 重新绘制x轴边缘密度直方图 for species, color in zip(g.hue_names, g.palette): subset = penguins[penguins['species'] == species] g.ax_marg_x.hist(subset['bill_length_mm'], bins=15, density=True, alpha=0.6, color=color, label=species) # 重新绘制y轴边缘密度直方图(横向) for species, color in zip(g.hue_names, g.palette): subset = penguins[penguins['species'] == species] g.ax_marg_y.hist(subset['bill_depth_mm'], bins=15, density=True, alpha=0.6, color=color, label=species, orientation='horizontal') # 添加图例 g.ax_marg_x.legend()
内容的提问来源于stack exchange,提问作者jialumaomao
相关产品推荐
相关产品推荐

