[英]Change stacked bar plot legend in Python
I have the following data in a csv file: 我在csv文件中包含以下数据:
Date City TruckA TruckB TruckC TruckD
Date1 City1 1 0 0 0
Date1 City2 0 0 1 0
Date1 City3 1 0 0 0
Date1 City4 0 0 1 0
Date2 City1 1 0 0 0
Date2 City2 0 1 0 0
Date2 City3 0 0 0 1
Date2 City4 1 0 0 0
Date2 City5 0 1 0 0
Date3 City1 1 0 0 0
Date3 City2 0 0 1 0
Date3 City3 1 0 0 0
Date3 City4 0 0 1 0
I can successfully plot the data with this code: 我可以使用以下代码成功绘制数据:
import pandas as pd
df = pd.read_csv("data.csv")
print(df)
df = df.set_index(["Date","City"])
df.unstack().plot(kind='bar', stacked=True)
I get the following result: 我得到以下结果:
As you can see, the color legend is such as each pair (City,Truck) has a color. 如您所见,颜色图例就像每对(城市,卡车)都有颜色。 I would like the legend to only depend on the Truck, and ideally have labels on the bar chart for each City.
我希望图例仅依赖于卡车,并且理想情况下在每个城市的条形图上都有标签。
Is this possible? 这可能吗?
Following @Scott's great answer you can get the stacked columns as desired. 遵循@Scott的绝佳回答,您可以根据需要获取堆叠的列。
import matplotlib.pyplot as plt
cycle = plt.rcParams['axes.prop_cycle'].by_key()['color']
df_out = df.unstack()
d = dict(zip(df.columns.get_level_values(0),cycle))
c = df_out.columns.get_level_values(0).map(d)
g=df_out.plot.bar(stacked=True, color=c, figsize=(10,8), edgecolor='k')
To add the labels thou you need to find the right position and label iteratively. 要添加标签,您需要找到正确的位置并反复进行标签。
Here is one way to do it: 这是一种实现方法:
h=0
x=0
unique_dates=df1.index.get_level_values(0).unique() # get the bars
city=df_out.iloc[x][df_out.iloc[x]!=0].dropna().index.get_level_values(1) #get the cities
for y,val in enumerate(df1.index.get_level_values(0)): #loop through the dates
if val==unique_dates[x]: #check the x position
g.text(x-0.05,1+h-0.5,"%s" % city[h])
h+=1
else: # move to next x coord, update city labels and add text for the next x coordinate (h=0)
x+=1
city=df_out.iloc[x][df_out.iloc[x]!=0].dropna().index.get_level_values(1) #get cities
g.text(x-0.05,1-0.5,"%s" % city[0])
h=1 # set h to 1 as we already printed for h=0
Original solution 原始解决方案
for x ,date in enumerate(df_out.index):
h=0
city=df_out.iloc[x][df_out.iloc[x]!=0].dropna().index.get_level_values(1) #get cities
for y,val in enumerate(df.index.get_level_values(0)):
if val==date:
g.text(x,1+h-0.5,"%s" % city[h])
h+=1
else:
continue
import matplotlib.pyplot as plt
cycle = plt.rcParams['axes.prop_cycle'].by_key()['color']
df_out = df.unstack()
d = dict(zip(df.columns.get_level_values(0),cycle))
c = df_out.columns.get_level_values(0).map(d)
df_out.plot.bar(stacked=True, color=c, figsize=(10,8))
Output: 输出:
Added edgecolor to set apart the cities: 添加了edgecolor以区分城市:
import matplotlib.pyplot as plt
cycle = plt.rcParams['axes.prop_cycle'].by_key()['color']
df_out = df.unstack()
d = dict(zip(df.columns.get_level_values(0),cycle))
c = df_out.columns.get_level_values(0).map(d)
df_out.plot.bar(stacked=True, color=c, figsize=(10,8), edgecolor='k')
IIUC, I think you are looking for something like this: IIUC,我认为您正在寻找这样的东西:
df = df.set_index(["Date","City"])
df.sum(level=0).plot.bar(stacked=True, figsize=(10,8))
Output: 输出:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.