'How to control the color of a specific column in a bar plot depending on it's xtick label?
I have a number of plots that show transcribed text from a speech to text engine in which I want to show the bars where the S2T engine transcribed correctly. I have labeled the subplots according to their expected values and now want to color the bars where the engine transcribed correctly in a different number than the other bars.
That means I need to access the color of the bars depending on their x-tick label. How do I do that?
Basically:
for xlabel in fig.xlabels:
if(xlabel.text == fig.title):
position = xlabel.position
fig.colorbar(position, 'red')
Code that is used to generate the plots:
def count_id(id_val, ax=None):
title = df.loc[df['ID'] == id_val, 'EXPECTED_TEXT'].iloc[0]
fig = df[df['ID']==id_val]['TRANSCRIPTION_STRING'].value_counts().plot(kind='bar', ax=ax, figsize=(20,6), title=title)
fig.set_xticklabels(fig.get_xticklabels(), rotation=40, ha ='right')
fig.yaxis.set_major_locator(MaxNLocator(integer=True))
fig, axs = plt.subplots(2, 4)
fig.suptitle('Classic subplot')
fig.subplots_adjust(hspace=1.4)
count_id('byte', axs[0,0])
count_id('clefting', axs[0,1])
count_id('left_hander', axs[0,2])
count_id('leftmost', axs[0,3])
count_id('right_hander', axs[1,0])
count_id('rightmost', axs[1,1])
count_id('wright', axs[1,2])
count_id('write', axs[1,3])
If anyone has an idea how to iterate over axs so I don't have to call count_id() 8 times, that'd be super helpful too. And yea I tried:
misses = ['byte', 'cleftig', 'left_hander', 'leftmost', 'right_hander', 'rightmost', 'wright', 'write']
for ax, miss in zip(axs.flat, misses):
count_id(ax, miss) # <- computer says no
Solution 1:[1]
You can set the color of each bar according to the label both before and after plotting the bars.
I will use the sample data below for demonstration.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
data = pd.DataFrame({'word': list('abcdefg'), 'number': np.arange(1, 8)})
1. Before plotting:
This is the most common way of plotting a colored barplot. Your can pass a list of colors to plt.plot().
def plot_color_label_before(data, target):
colors = ['red' if word == target else 'blue' for word in data.word]
bars = plt.bar(x=data.word, height=data.number, color=colors, alpha=0.5)
The data passed to the function contains two columns, where the first lists all the words on your xtick, and the second lists the corrsponding numbers. The target is your expected word.
The code determines the colors for each word according to whether it is consistent with your target. For example,
plot_color_label_before(data, 'c')
2. After plotting:
If you want to access the color after calling plt.plot, use set_color to change the color of a specific bar.
def plot_color_label_after(data, target):
bars = plt.bar(x=data.word, height=data.number, color='blue', alpha=0.5)
for idx, word in enumerate(data.word):
if word == target:
bars[idx].set_color(c='yellow')
plt.bar returns a BarContainer, the i-th element of which is a patch (rectangle). Iterate over all the labels and change the color if the word hits the target.
For example,
plot_color_label_after(data, 'c')
Finally, as to iterating over axs, just ravel it can solve the problem.
fig, axs = plt.subplots(2, 4)
for ax in axs.ravel():
ax.plot(...)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Cheng |



