如何用Python创建基于自定义值的堆叠条形图?解决plotnine报错
问题描述
我有如下简化后的Pandas DataFrame:
df = pd.DataFrame([ ("Distal Lung AT2", 0.4269588779192778, 20), ("Lung Ciliated epithelial cells", 0.28642167657082035, 20), ("Distal Lung AT2",0.4488207834077291,15), ("Lung Ciliated epithelial cells", 0.27546336897259094, 15), ("Distal Lung AT2", 0.45502553604960105, 10), ("Lung Ciliated epithelial cells", 0.29080413886147555, 10), ("Distal Lung AT2", 0.48481604554028446, 5), ("Lung Ciliated epithelial cells", 0.3178232409599174, 5)], columns = ["features", "importance", "num_features"])
需要创建满足以下要求的堆叠条形图:
- x轴为
num_features,相同值的行分组展示 - y轴为
importance列的数值 - 每个条形按
features字段区分颜色
尝试用plotnine实现,代码如下:
plot = ( ggplot(df, aes(x="num_features", y="importance", fill="features")) + geom_bar(stat="identity") + xlab("Number of Features") + ylab("") )
但执行ggsave(plot, os.path.join(figure_path, "stacked_feature_importances.png"))保存时,触发以下报错:
Traceback (most recent call last): File "/home/mdanb/plot_top_features_iteratively.py", line 94, in <module> plot_stacked_bar_plots(backwards_elim_dirs) File "/home/mdanb/plot_top_features_iteratively.py", line 87, in plot_stacked_bar_plots ggsave(plot, os.path.join(figure_path, "stacked_feature_importances.png")) File "/home/mdanb/.local/lib/python3.8/site-packages/plotnine/ggplot.py", line 736, in ggsave return plot.save(*arg, **kwargs) File "/home/mdanb/.local/lib/python3.8/site-packages/plotnine/ggplot.py", line 724, in save fig, p = self.draw(return_ggplot=True) File "/home/mdanb/.local/lib/python3.8/site-packages/plotnine/ggplot.py", line 203, in draw self._build() File "/home/mdanb/.local/lib/python3.8/site-packages/plotnine/ggplot.py", line 311, in _build layers.compute_position(layout) File "/home/mdanb/.local/lib/python3.8/site-packages/plotnine/layer.py", line 79, in compute_position l.compute_position(layout) File "/home/mdanb/.local/lib/python3.8/site-packages/plotnine/layer.py", line 393, in compute_position data = self.position.compute_layer(data, params, layout) File "/home/mdanb/.local/lib/python3.8/site-packages/plotnine/positions/position.py", line 56, in compute_layer return groupby_apply(data, 'PANEL', fn) File "/home/mdanb/.local/lib/python3.8/site-packages/plotnine/utils.py", line 638, in groupby_apply lst.append(func(d, *args, **kwargs)) File "/home/mdanb/.local/lib/python3.8/site-packages/plotnine/positions/position.py", line 54, in fn return cls.compute_panel(pdata, scales, params) File "/home/mdanb/.local/lib/python3.8/site-packages/plotnine/positions/position_stack.py", line 85, in compute_panel trans = scales.y.trans AttributeError: 'scale_y_discrete' object has no attribute 'trans'
另外试过直接用Pandas绘图,但它的堆叠条形图默认是基于计数统计,没法实现按importance数值堆叠的需求。
解决方案
修复plotnine的报错
报错核心原因是plotnine错误地将y轴识别为离散型(discrete),而堆叠计算需要连续型(continuous)的y轴。只需手动指定y轴类型即可解决:
修改后的plotnine代码:
plot = ( ggplot(df, aes(x="num_features", y="importance", fill="features")) + geom_bar(stat="identity") + xlab("Number of Features") + ylab("") + scale_y_continuous() # 强制指定y轴为连续型 )
另一种思路是把num_features转为字符串类型,避免plotnine混淆x轴的类型判断,同时确保y轴保持连续:
df['num_features'] = df['num_features'].astype(str) plot = ( ggplot(df, aes(x="num_features", y="importance", fill="features")) + geom_bar(stat="identity", position="stack") + xlab("Number of Features") + ylab("") )
用matplotlib实现需求
如果不想用plotnine,也可以用matplotlib配合数据透视来实现:
import matplotlib.pyplot as plt # 将数据透视成适合堆叠绘图的格式 pivot_df = df.pivot(index='num_features', columns='features', values='importance').fillna(0) # 绘制堆叠条形图 pivot_df.plot(kind='bar', stacked=True) plt.xlabel('Number of Features') plt.ylabel('') plt.savefig(os.path.join(figure_path, "stacked_feature_importances.png"))
内容的提问来源于stack exchange,提问作者An Ignorant Wanderer
相关产品推荐
相关产品推荐

