简体   繁体   English

Matplotlib条形图-类似于堆积的叠加条

[英]Matplotlib bar chart - overlay bars similar to stacked

I want to create a matplotlib bar plot that has the look of a stacked plot without being additive from a multi-index pandas dataframe. 我想创建一个matplotlib条形图,该条形图具有堆叠图的外观,而无需从多索引熊猫数据框中添加。

The below code gives the basic behaviour 下面的代码给出了基本行为

%matplotlib notebook
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import io

data = io.StringIO('''Fruit,Color,Price
Apple,Red,1.5
Apple,Green,1.0
Pear,Red,2.5
Pear,Green,2.3
Lime,Green,0.5
Lime, Red, 3.0
''')
df_unindexed = pd.read_csv(data)
df_unindexed
df = df_unindexed.set_index(['Fruit', 'Color'])
df.unstack().plot(kind='bar')

The plot command df.unstack().plot(kind='bar') shows all the apple prices grouped next to each other. 绘图命令df.unstack().plot(kind='bar')显示了彼此相邻分组的所有苹果价格。 If you choose the option df.unstack().plot(kind='bar',stacked=True) - it adds the prices for Red and Green together and stacks them. 如果选择选项df.unstack().plot(kind='bar',stacked=True) -它将红色和绿色的价格加在一起并堆叠。

I am wanting a plot that is halfway between the two - it shows each group as a single bar, but overlays the values so you can see them all. 我想要一个介于两者之间的绘图-它将每个组显示为单个条形,但是覆盖了值,以便您可以全部看到它们。 The below figure (done in powerpoint) shows what behaviour I am looking for -> I want the image on the right. 下图(在powerpoint中完成)显示了我正在寻找的行为->我想要右侧的图像。

Short of calculating all the values and then using the stacked option, is this possible? 如果不计算所有值,然后使用堆叠选项,这可能吗?

条形图示例

This seems (to me) like a bad idea, since this representation leads to several problem. 在我看来,这似乎是个坏主意,因为这种表示方式会导致多个问题。 Will a reader understand that those are not staked bars? 读者会理解那些不是抵押的吗? What happens when the front bar is taller than the ones behind? 如果前杠比后杠高,会发生什么?

In any case, to accomplish what you want, I would simply repeatedly call plot() on each subset of the data and using the same axes so that the bars are drawn on top of each other. 无论如何,要完成您想要的工作,我只需在数据的每个子集上使用相同的轴重复调用plot() ,以便将条形图绘制在彼此之上。 In your example, the "Red" prices are always higher, so I had to adjust the order to plot them in the back, or they would hide the "Green" bars. 在您的示例中,“红色”价格始终较高,因此我必须调整顺序以将其绘制在背面,否则它们将隐藏“绿色”条。

fig,ax = plt.subplots()

my_groups = ['Red','Green']
df_group = df_unindexed.groupby("Color")

for color in my_groups:
    temp_df = df_group.get_group(color)
    temp_df.plot(kind='bar', ax=ax, x='Fruit', y='Price', color=color, label=color)

在此处输入图片说明

There are two problems with this kind of plot. 这种情节有两个问题。 (1) What if the background bar is smaller than the foreground bar? (1)如果背景栏小于前景栏怎么办? It would simply be hidden and not visible. 它只会被隐藏而不可见。 (2) A chart like this is not distinguishable from a stacked bar chart. (2)此类图表无法与堆叠条形图区分开。 Readers will have severe problems interpreting it. 读者在解释它时会遇到严重的问题。

That being said, you can plot both columns individually. 话虽如此,您可以分别绘制两个列。

import matplotlib.pyplot as plt
import pandas as pd
import io

data = io.StringIO('''Fruit,Color,Price
Apple,Red,1.5
Apple,Green,1.0
Pear,Red,2.5
Pear,Green,2.3
Lime,Green,0.5
Lime,Red,3.0''')

df_unindexed = pd.read_csv(data)
df = df_unindexed.set_index(['Fruit', 'Color']).unstack()
df.columns = df.columns.droplevel()

plt.bar(df.index, df["Red"].values, label="Red")
plt.bar(df.index, df["Green"].values, label="Green")
plt.legend()
plt.show()

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM