Color matplotlib bar chart based on value

Posted on

Question :

Color matplotlib bar chart based on value

Is there a way to color the bars of a barchart based on the bar’s value. For example:

- values below -0.5: red
- values between -0.5 to 0: green
- values between 0 to 08: blue
- etc

I have found some basic examples of bar coloring but nothing which can cater for value ranges, such as the above examples.


Thank you kikocorreoso for your suggestion. This works great when both axes are numbers as per your example. However in my case my original data structure is a pandas dataframe. I then use df.stack() and plot the result. This means that the dataframes rows/columns become the x axis of the plot and the dataframe cells are the Y axis (bars).

I have tried masking as per your example but it doesn’t seem to work when the Y axis are numbers and the X axis are names. eg:

     col1    col2   col3   col4
 row1 1       2      3      4
 row2 5       6      7      8
 row3 9       10     11     12
 row4 13      14     15     16

The above dataframe needs to be plotted as a barchart with the row/column combinations forming the x-axis. Each cell value will be a bar. And ultimately, coloring the bars as per the original question. Thanks

Asked By: darkpool


Answer #1:

You could use masks for your datasets. A basic example could be the following:

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(10)
y = np.arange(10) * 0.1

mask1 = y < 0.5
mask2 = y >= 0.5[mask1], y[mask1], color = 'red')[mask2], y[mask2], color = 'blue')

The result should be:
enter image description here


As you updated your question I update the code. For your simple case, and if I understood correctly, you could do the following (ugly) hack:

import pandas as pd

df = pd.DataFrame({'col1':[1,2,3], 'col2':[4,5,6]}, 
                  index = ['row1','row2','row3'])

dfstacked = df.stack()

mask = dfstacked <= 3

colors = np.array(['b']*len(dfstacked))
colors[mask.values] = 'r'

dfstacked.plot(kind = 'bar', rot = 45, color = colors)

Or use a more OO solution.

The code briefly explained:

  • I create a mask for my red columns
  • I create an array of colors
  • Change the the array of colors in order to use other color for my masked values
  • As the dfstacked dataframe has a MultiIndex the ticks are not well printed so I use the rot keyword to rotate them. If you want to automate it in order to get a nice plot you can use plt.tight_layout() before

I hope it helps.

Answered By: darkpool

Answer #2:

I see this question has been asked a long time ago already, but just in case it could help someone, this is what worked for me:

Iterate over all values and append colors to a list depending on customized conditions, so you get a list with as many color specifications as you have values; then use the color list in

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(10)
y = np.arange(10) * 0.1

col = []
for val in y:
    if val < 0.4:
    elif val >= 0.7:

# col looks like this: ['blue', 'blue', 'blue', 'blue', 'red', 'red', 'red', 'green', 'green', 'green'], y, color = col)

Answered By: kikocorreoso

Answer #3:

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(4)
y = np.array([-2,3,-1,2])
for n,val in enumerate(y):
    if val<0:
    elif val>=0
        cc[n]='blue', y, color = cc)

enter image description here

Answered By: KauBee3

Leave a Reply

Your email address will not be published. Required fields are marked *