Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bar graph color dependent on value in Matplotlib

I've created a bar graph, as follows:

from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
import matplotlib.pyplot as plt

#self.Data1 is an array containing all the data points, inherited from a separate class

DataSet = range(46)
self.Figure1 = plt.figure()
self.Figure1.patch.set_alpha(0)
self.Canvas1 = FigureCanvas(self.Figure1)

#Add canvas to pre-existing Widget#
self.Widget.addWidget(self.Canvas1)
self.Ax1 = plt.subplot(1, 1, 1, axisbg='black')
self.Ax1.bar(DataSet, self.Data1, width=1, color='r')
self.Ax1.tick_params(axis='y', colors='white')
plt.title('GRAPH TITLE', color='w', fontsize=30, fontname='Sans Serif', fontweight='bold')
self.Figure1.tight_layout()

This is working nicely, producing the following graph:

Current graph

What I'd like to do is set the bar color depending on the value. I.e. blue if the value is positive and red if the value is negative. What's the easiest way to do so? Do I need to create a Color Map?

like image 992
jars121 Avatar asked Dec 02 '25 22:12

jars121


2 Answers

You can also specify an arraylike as the color kwarg as such:

x = np.arange(1,100)
y = np.sin(np.arange(1,100))
colors = np.array([(1,0,0)]*len(y))
colors[y >= 0] = (0,0,1)
plt.bar(x,y,color = colors)

So long as colors is the same length as y, you can specify the colors however you want.

enter image description here

Or for something a little fancier:

x = np.arange(1,100)
y = np.sin(3*np.arange(1,100))
colors = np.array([(1,0,0)]*len(y))
colors[y >= 0] = (0,0,1)
mult = np.reshape(np.repeat(np.abs(y)/np.max(np.abs(y)),3),(len(y),3))
colors =  mult*colors
plt.bar(x,y,color = colors)

enter image description here

like image 122
csunday95 Avatar answered Dec 04 '25 12:12

csunday95


This is by far not the best solution in terms of reusability and/or scalability, but if you only want to have red bars for negative numbers and blue bars for positive number, you can call the barplot twice, by filtering the values before hand. Here is a minimal example of what I mean:

import numpy as np
import matplotlib.pylab as pl

array = np.random.randn(100)
greater_than_zero = array > 0
lesser_than_zero = array < 0
cax = pl.subplot(111)
cax.bar(np.arange(len(array))[greater_than_zero], array[greater_than_zero], color='b')
cax.bar(np.arange(len(array))[lesser_than_zero], array[lesser_than_zero], color='r')

result http://img11.hostingpics.net/pics/547091download.png

like image 24
Challensois Avatar answered Dec 04 '25 13:12

Challensois



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!