猿问

使用辅助轴线图制作分类或分组条形图

我需要使用条形图和折线图比较 4 个班次(分类/分组)之间的不同日常数据集。我到处寻找,但没有找到一个可行的解决方案,其中不包括生成新的支点等。


我已经使用了 matplotlib 和 seaborn,虽然我可以做一个或另一个(每个班次的不同颜色的条/线),一旦我合并另一个,要么消失,要么其他异常发生,就像只有一个情节点显示. 我已经查看了所有的解决方案,可以在两种图表类型上表示单个系列的数据,但没有一个属于多类别或针对这两种类型进行分组。


数据示例:


report_date wh_id   shift   Head_Count  UTL_R

3/17/19     55  A   72  25%

3/18/19     55  A   71  10%

3/19/19     55  A   76  20%

3/20/19     55  A   59  33%

3/21/19     55  A   65  10%

3/22/19     55  A   54  20%

3/23/19     55  A   66  14%

3/17/19     55  1   11  10%

3/17/19     55  2   27  13%

3/17/19     55  3   18  25%

3/18/19     55  1   23  100%

3/18/19     55  2   16  25%

3/18/19     55  3   12  50%

3/19/19     55  1   28  10%

3/19/19     55  2   23  50%

3/19/19     55  3   14  33%

3/20/19     55  1   29  25%

3/20/19     55  2   29  25%

3/20/19     55  3   10  50%

3/21/19     55  1   17  20%

3/21/19     55  2   29  14%

3/21/19     55  3   30  17%

3/22/19     55  1   12  14%

3/22/19     55  2   10  100%

3/22/19     55  3   17  14%

3/23/19     55  1   16  10%

3/23/19     55  2   11  100%

3/23/19     55  3   13  10%

tm_daily_df = pd.read_csv('fg_TM_Daily.csv')

tm_daily_df = tm_daily_df.set_index('report_date')

fig2, ax2 = plt.subplots(figsize=(12,8))

ax3 = ax2.twinx()

group_obj = tm_daily_df.groupby('shift')

g = group_obj['Head_Count'].plot(kind='bar', x='report_date',  y='Head_Count',ax=ax2,stacked=False,alpha = .2)

g = group_obj['UTL_R'].plot(kind='line',x='report_date', y='UTL_R', ax=ax3,marker='d', markersize=12)

plt.legend(tm_daily_df['shift'].unique())

这段代码让我得到了最接近的结果。请注意,即使使用stacked = False,它们仍然堆叠在一起。我将设置更改为 True,没有任何变化。


我所需要的只是让条形彼此相邻,并具有代表班次的相同配色方案


图表:

一只甜甜圈
浏览 165回答 2
2回答

紫衣仙女

这里有两种解决方案(堆叠和非堆叠)。根据您的问题,我们将:Head_Count在左 y 轴和UTL_R右 y 轴上绘图。report_date 将是我们的 x 轴shift 将代表我们图形的色调。堆叠版本使用pandas默认绘图功能,非堆叠版本使用seaborn.编辑根据您的要求,我添加了一个 100% 堆叠图。虽然这与您在评论中所问的不完全相同,但您询问的图形类型可能会在阅读时造成一些混乱(是基于堆栈的上线或堆栈宽度的值)。另一种解决方案可能是使用 100% 堆叠图。堆叠import pandas as pdimport seaborn as snsimport matplotlib.pyplot as pltdfg = df.set_index(['report_date', 'shift']).sort_index(level=[0,1])fig, ax = plt.subplots(figsize=(12,6))ax2  = ax.twinx()dfg['Head_Count'].unstack().plot.bar(stacked=True, ax=ax, alpha=0.6)dfg['UTL_R'].unstack().plot(kind='line', ax=ax2, marker='o', legend=None)ax.set_title('My Graph')plt.show()堆叠 100%import pandas as pdimport seaborn as snsimport matplotlib.pyplot as pltdfg = df.set_index(['report_date', 'shift']).sort_index(level=[0,1])# Create `Head_Count_Pct` columnfor date in dfg.index.get_level_values('report_date').unique():    for shift in dfg.loc[date, :].index.get_level_values('shift').unique():        dfg.loc[(date, shift), 'Head_Count_Pct'] = dfg.loc[(date, shift), 'Head_Count'].sum() / dfg.loc[(date, 'A'), 'Head_Count'].sum()fig, ax = plt.subplots(figsize=(12,6))ax2  = ax.twinx()pal = sns.color_palette("Set1")dfg[dfg.index.get_level_values('shift').isin(['1','2','3'])]['Head_Count_Pct'].unstack().plot.bar(stacked=True, ax=ax, alpha=0.5, color=pal)dfg['UTL_R'].unstack().plot(kind='line', ax=ax2, marker='o', legend=None, color=pal)ax.set_title('My Graph')plt.show()未堆叠import pandas as pdimport seaborn as snsimport matplotlib.pyplot as pltdfg = df.set_index(['report_date', 'shift']).sort_index(level=[0,1])fig, ax = plt.subplots(figsize=(15,6))ax2  = ax.twinx()sns.barplot(x=dfg.index.get_level_values('report_date'),            y=dfg.Head_Count,           hue=dfg.index.get_level_values('shift'), ax=ax, alpha=0.7)sns.lineplot(x=dfg.index.get_level_values('report_date'),            y=dfg.UTL_R,           hue=dfg.index.get_level_values('shift'), ax=ax2, marker='o', legend=None)ax.set_title('My Graph')plt.show()编辑#2这是您第二次请求的图形(堆叠,但堆栈 n+1 不在堆栈 n 结束的地方开始)。它稍微涉及更多,因为我们必须做多件事: - 我们需要手动将颜色分配给我们shift的 df - 一旦我们分配了颜色,我们将遍历每个日期范围和 1)排序或Head_Count值降序(所以当我们绘制图形时,我们最大的麻袋在后面),以及 2)绘制数据并将颜色分配给每个 stacj - 然后我们可以创建第二个 y 轴并绘制我们的UTL_R值 - 然后我们需要分配正确的颜色到我们的传奇标签import pandas as pdimport seaborn as snsimport matplotlib.pyplot as pltdef assignColor(shift):    if shift == 'A':        return 'R'    if shift == '1':        return 'B'    if shift == '2':        return 'G'    if shift == '3':        return 'Y'# map a color to a shiftdf['color'] = df['shift'].apply(assignColor)fig, ax = plt.subplots(figsize=(15,6))# plot our Head_Count valuesfor date in df.report_date.unique():    d = df[df.report_date == date].sort_values(by='Head_Count', ascending=False)    y = d.Head_Count.values    x = date    color = d.color    b = plt.bar(x,y, color=color)# Plot our UTL_R valuesax2 = ax.twinx()    sns.lineplot(x=df.report_date, y=df.UTL_R, hue=df['shift'], marker='o', legend=None)# Assign the color label color to our legendleg = ax.legend(labels=df['shift'].unique(), loc=1)legend_maping = dict()for shift in df['shift'].unique():    legend_maping[shift] = df[df['shift'] == shift].color.unique()[0]i = 0for leg_lab in leg.texts:    leg.legendHandles[i].set_color(legend_maping[leg_lab.get_text()])    i += 1

慕无忌1623718

这个怎么样?tm_daily_df['UTL_R'] = tm_daily_df['UTL_R'].str.replace('%', '').astype('float') / 100pivoted = tm_daily_df.pivot_table(values=['Head_Count', 'UTL_R'],                                   index='report_date',                                   columns='shift')pivoted#             Head_Count             UTL_R# shift                1   2   3   A     1     2     3     A# report_date# 3/17/19             11  27  18  72  0.10  0.13  0.25  0.25# 3/18/19             23  16  12  71  1.00  0.25  0.50  0.10# 3/19/19             28  23  14  76  0.10  0.50  0.33  0.20# 3/20/19             29  29  10  59  0.25  0.25  0.50  0.33# 3/21/19             17  29  30  65  0.20  0.14  0.17  0.10# 3/22/19             12  10  17  54  0.14  1.00  0.14  0.20# 3/23/19             16  11  13  66  0.10  1.00  0.10  0.14fig, ax = plt.subplots()pivoted['Head_Count'].plot.bar(ax=ax)pivoted['UTL_R'].plot.line(ax=ax, legend=False, secondary_y=True, marker='D')ax.legend(loc='upper left', title='shift')
随时随地看视频慕课网APP

相关分类

Python
我要回答