如何用Seaborn Objects高效实现正负轴分色的龙卷风图?
使用Seaborn Objects实现龙卷风图(单图表方案)
要实现将不同性别的直方图分别放在正负轴的龙卷风图,无需拼接多个图表,核心思路是调整对应类别的计数符号,直接在单图表中绘制。以下是具体实现:
代码示例
import numpy as np import pandas as pd import seaborn.objects as so # 生成随机数据 df = pd.DataFrame({ 'id': np.random.randint(0, 1000, 100), 'gender': np.random.choice(['m', 'f'], 100), 'age': np.random.randint(18, 100, 100) }) # 自定义转换函数:生成龙卷风图所需的带符号计数数据 def prepare_tornado_data(data, group_col="gender", negative_group="f", age_bins=10): # 按年龄分箱、性别分组统计频数 binned_counts = ( data.groupby([pd.cut(data["age"], bins=age_bins), group_col]) .size() .reset_index(name="count") ) # 将指定类别的计数转为负数 binned_counts["count"] = np.where( binned_counts[group_col] == negative_group, -binned_counts["count"], binned_counts["count"] ) return binned_counts # 绘制龙卷风图 ( so.Plot(prepare_tornado_data(df), x="age", y="count", color="gender") .add(so.Bars()) .label(y="频数") # 将Y轴刻度显示为绝对值,提升可读性 .scale(y=so.Continuous().tickformat(lambda x: f"{abs(int(x))}")) # 可选:移除左右脊柱,优化视觉效果 .theme({"axes.spines.left": False, "axes.spines.right": False}) )
方案说明
- 数据转换逻辑:通过提前计算年龄分箱后的性别频数,将其中一类的计数取负,绘制条形图时该类会自动显示在负轴区域,另一类在正轴,形成龙卷风图的布局。
- 单图表实现:全程基于同一个
so.Plot对象构建,无需拼接多个图表。 - 多类别适配性:如果
gender列有超过2个类别,可扩展转换逻辑(例如将类别分为正负两组),但龙卷风图通常以两类对比为主,多类场景需注意视觉可读性。 - 细节优化:通过
tickformat将Y轴刻度显示为绝对值,避免负号干扰数据解读,同时可通过主题设置简化图表样式。
内容的提问来源于stack exchange,提问作者divingTobi
相关产品推荐
相关产品推荐

