2

I have two vectors, for example

price1 = [28688, 28241, 30091]  
price2 =[27285, 29924, 35291]   

that I need to put in a histogram in order to visualize the differences and to compare them element by element. What I have tried was

ind = np.arange(N)
width = 0.2     
a1 = plt.bar(ind, price1, width, color='black')
b1 = plt.bar(ind, price2, width, color='red')

but the histogram generated has a problem: if an element of price1 (in this example the last two) is lesser than the corresponding element of price2, in the figure I don't see its relative bar, while if it's greater is ok. I wish I could see both values in each case.

enter image description here

P.s. since I have several couples of vectors to compare in the same figure, I can't simply put the two bars side by side, in order to avoid confusion I would like to have, for each bar two values.

Edited: Fix code indent. change the variable names from price0, price1 to price1, pirce2.

dkato
  • 895
  • 10
  • 28

2 Answers2

2

In order to have the smallest bar in front you may sort your data. Putting it into a column array makes that very easy. You can then loop through the sorted array to plot the bars according to their height - starting with the highest in the background. Colorizing can be done according to the argument-sorted array and a ListedColormap.

import matplotlib.pyplot as plt
import matplotlib.colors
import numpy as np

price1 = [28688, 28241, 30091]
price2 = [27285, 29924, 35291]   
prices = np.c_[price1,price2]

asort = np.argsort(prices,axis=1)
sort = np.sort(prices,axis=1)

cmap=matplotlib.colors.ListedColormap(["black", "red"])
ind = np.arange(prices.shape[0])
width = 0.2 

for i in range(prices.shape[1]-1,-1,-1):
    plt.bar(ind, sort[:,i], width, color=cmap(asort[:,i]))    

plt.show()

enter image description here

The good thing is that this is easily extendable to more lists of prices; we just need to add another list to the array and another color to the colormap.

import matplotlib.pyplot as plt
import matplotlib.colors
import numpy as np

price1 = [28688, 28241, 30091]
price2 = [27285, 29924, 35291]
price3 = [26000, 29000, 36000]
prices = np.c_[price1,price2,price3]

asort = np.argsort(prices,axis=1)
sort = np.sort(prices,axis=1)

cmap=matplotlib.colors.ListedColormap(["black", "red", "C0"])
ind = np.arange(prices.shape[0])
width = 0.2 

for i in range(prices.shape[1]-1,-1,-1):
    plt.bar(ind, sort[:,i], width, color=cmap(asort[:,i]))    

plt.show()

enter image description here

ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712
1

I think you need to check each element and change the plot order.

import numpy as np
import matplotlib.pyplot as plt

N = 3

price1 = [28688, 28241, 30091]
price2 =[27285, 29924, 35291]

ind = np.arange(N)
width = 0.2
bar_handlers_a = []
bar_handlers_b = []
for i, p1, p2 in zip(ind, price1, price2):
    if p1 < p2:
        b1 = plt.bar(i, p2, width, color='red')
        a1 = plt.bar(i, p1, width, color='black')
    else:
        a1 = plt.bar(i, p1, width, color='black')
        b1 = plt.bar(i, p2, width, color='red')

    bar_handlers_a.append(a1)
    bar_handlers_b.append(b1)

plt.show()
dkato
  • 895
  • 10
  • 28