Home > Software engineering >  How to change the default group color for grouped bars
How to change the default group color for grouped bars

Time:11-27

Code which I found enter image description here

Using the answer cited in the OP

  • for i, (gr, color) in enumerate(zip(subx, colors)): allows for assigning a color from the list to each group.
def grouped_barplot(df, cat,subcat, val , err):
    u = df[cat].unique()
    x = np.arange(len(u))
    subx = df[subcat].unique()
    offsets = (np.arange(len(subx))-np.arange(len(subx)).mean())/(len(subx) 1.)
    width= np.diff(offsets).mean()

    colors = ['black', 'red', 'green', 'blue', 'cyan','brown','grey','goldenrod','lime','violet','indigo','coral','olive']
    
    # add the colors to the loop
    for i, (gr, color) in enumerate(zip(subx, colors)):
        dfg = df[df[subcat].eq(gr)]
        plt.bar(x offsets[i], dfg[val], width=width, yerr=dfg[err], color=color, label=gr)
 
    plt.legend(title='Sample_Set', bbox_to_anchor=(1, 1.02), loc='upper left')
    plt.yscale('log')
    plt.xlabel(cat)
    plt.ylabel(val)
    plt.xticks(x, u)
    plt.show()


cat = "Candidate"
subcat = "Sample_Set"
val = "Values"
err = "Error"

grouped_barplot(df, cat, subcat, val, err )

Original Answer

  • The request can be implemented, but should not be:
    • This is not a good visualization practice. The bars within a given group should all have the same color. The point of a visualization is to convey information. All this will do is make the plot confusing to read, thereby defeating the purpose.
  • Because the the bars are plotted in groups: 'X', 'Y', 'Z' of 'Sample_Set 1', 'X', 'Y', 'Z' of 'Sample_Set 2' and 'X', 'Y', 'Z' of 'Sample_Set 3', only 3 labels will be created in the legend, which means a custom patch legend with appropriate handles and labels will need to be created.

Plot and Customize

  • The order of rects is not the same as df, so df is sorted differently in order to zip the correct color to the correct rect
# add a colors column to the dataframe
df['color'] = colors[:len(df)]

# plot vals with yerr
ax = vals.plot(kind='bar', yerr=yerr, logy=True, rot=0, figsize=(6, 5), legend=False, ylabel='Value', title='Comparison')

# extract the Rectangle bar objects
rects = [c for c in ax.get_children() if isinstance(c, mpl.patches.Rectangle)]

# change the face color of the bar
for rect, color in zip(rects, df.sort_values(['Sample_Set', 'Candidate'])['color']):
    rect.set_fc(color)

# create a custom handle for the legend
handles = list()
for idx, v in df.iterrows():
    patch = Patch(color=v.color, label=f'{v.Candidate} {v.Sample_Set}')
    handles.append(patch)    

# add the legend
ax.legend(title='Candidate Sample_Set', handles=handles, bbox_to_anchor=(1, 1.02), loc='upper left')

plt.show()

enter image description here

Using the enter image description here

  • Related