Skip to main content
 首页 » 编程设计

python之在 Python 中更改堆积条形图图例

2025年05月04日22oomusou

我在一个 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 

我可以用这段代码成功绘制数据:

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) 

我得到以下结果: Image

如您所见,颜色图例例如每对 (City,Truck) 都有一种颜色。我希望图例仅取决于卡车,并且理想情况下在每个城市的条形图上都有标签。

这可能吗?

请您参考如下方法:

按照@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') 

要添加标签,您需要反复找到正确的位置和标签。
这是一种方法:

编辑:只有一个循环

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 

原解

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