11

I want to plot a bar chart or a histogram using matplotlib. I don't want a stacked bar plot, but a superimposed barplot of two lists of data, for instance I have the following two lists of data with me:

Some code to begin with :

import matplotlib.pyplot as plt
from numpy.random import normal, uniform

highPower   = [1184.53,1523.48,1521.05,1517.88,1519.88,1414.98,1419.34,
              1415.13,1182.70,1165.17]
lowPower    = [1000.95,1233.37, 1198.97,1198.01,1214.29,1130.86,1138.70,
               1104.12,1012.95,1000.36]

plt.hist(highPower, bins=10, histtype='stepfilled', normed=True,
         color='b', label='Max Power in mW')
plt.hist(lowPower, bins=10, histtype='stepfilled', normed=True,
         color='r', alpha=0.5, label='Min Power in mW')

I want to plot these two lists against the number of values in the two lists such that I am able to see the variation per reading.

4
  • yes I am posting it in the edit of the question Commented Apr 25, 2014 at 12:22
  • take a look at numpy.cumsum() and pyplot.hist()... Commented Apr 25, 2014 at 12:22
  • pyplot.hist() how do I use that? Commented Apr 25, 2014 at 12:23
  • @Ffisegydd any help you can offer? Commented Apr 25, 2014 at 12:28

3 Answers 3

20

You can produce a superimposed bar chart using plt.bar() with the alpha keyword as shown below.

The alpha controls the transparency of the bar.

N.B. when you have two overlapping bars, one with an alpha < 1, you will get a mixture of colours. As such the bar will appear purple even though the legend shows it as a light red. To alleviate this I have modified the width of one of the bars, this way even if your powers should change you will still be able to see both bars.

plt.xticks can be used to set the location and format of the x-ticks in your graph.

import matplotlib.pyplot as plt
import numpy as np

width = 0.8

highPower   = [1184.53,1523.48,1521.05,1517.88,1519.88,1414.98,
               1419.34,1415.13,1182.70,1165.17]
lowPower    = [1000.95,1233.37, 1198.97,1198.01,1214.29,1130.86,
               1138.70,1104.12,1012.95,1000.36]

indices = np.arange(len(highPower))

plt.bar(indices, highPower, width=width, 
        color='b', label='Max Power in mW')
plt.bar([i+0.25*width for i in indices], lowPower, 
        width=0.5*width, color='r', alpha=0.5, label='Min Power in mW')

plt.xticks(indices+width/2., 
           ['T{}'.format(i) for i in range(len(highPower))] )

plt.legend()

plt.show()

Plot

Sign up to request clarification or add additional context in comments.

6 Comments

There is no values in the list that exceeds 2000, then how does this bar chart show a value greater than 2000 and the labels on the x-axis have to be [1,2,3,4,.....,10] but it shows in the increments of 2
I don't want them stacked on top of each other rather they should be superimposing each other that is lower value should occupy some region of the bar with a higher value
Great, this works, thankyou for the explanation too :) but how do I modify the ticks on the x axis to be T1,T2,T3 and so on
I have added an example of how to set the x-ticks to be "T1", "T2", etc. In the future however I would advise that you either explain your question fully at the beginning (not add more sub-questions on as you go) or simply ask a new question for your extended questions.
when I run this code, the red bars show on the right side of the blue bar, instead of the middle. Can you update the code?
|
7

It is actually simpler than the answers all over the internet make it appear.

a = range(1,10)
b = range(4,13)
ind = np.arange(len(a))

fig = plt.figure()
ax = fig.add_subplot(111)
ax.bar(x=ind, height=a, width=0.35,align='center')
ax.bar(x=ind, height=b, width=0.35/3,  align='center')

plt.xticks(ind, a)

plt.tight_layout()
plt.show()

enter image description here

Comments

6

Building on @Ffisegydd's answer, if your data is in a Pandas DataFrame, this should work nicely:

def overlapped_bar(df, show=False, width=0.9, alpha=.5,
                   title='', xlabel='', ylabel='', **plot_kwargs):
    """Like a stacked bar chart except bars on top of each other with transparency"""
    xlabel = xlabel or df.index.name
    N = len(df)
    M = len(df.columns)
    indices = np.arange(N)
    colors = ['steelblue', 'firebrick', 'darksage', 'goldenrod', 'gray'] * int(M / 5. + 1)
    for i, label, color in zip(range(M), df.columns, colors):
        kwargs = plot_kwargs
        kwargs.update({'color': color, 'label': label})
        plt.bar(indices, df[label], width=width, alpha=alpha if i else 1, **kwargs)
        plt.xticks(indices + .5 * width,
                   ['{}'.format(idx) for idx in df.index.values])
    plt.legend()
    plt.title(title)
    plt.xlabel(xlabel)
    plt.ylabel(ylabel)
    if show:
        plt.show()
    return plt.gcf()

And then in a python command line:

low = [1000.95, 1233.37, 1198.97, 1198.01, 1214.29, 1130.86, 1138.70, 1104.12, 1012.95, 1000.36]
high = [1184.53, 1523.48, 1521.05, 1517.88, 1519.88, 1414.98, 1419.34, 1415.13, 1182.70, 1165.17]
df = pd.DataFrame(np.matrix([high, low]).T, columns=['High', 'Low'],
                  index=pd.Index(['T%s' %i for i in range(len(high))],
                  name='Index'))
overlapped_bar(df, show=False)

overlapped bar chart in matplotlib

4 Comments

Trying this code and it displays the bar chart twice, Can the code be edited so it only displays the graph once?
How would you also change the fig size for this graph? I cannot seem to change it doing it the standard way
@CathalBrady are you using Spider? What is your python environment? This code will only work in a full python environment with matplotlib and its backend configured correctly for your OS or environment. You'll have to do something slightly different in a Jupyter Notebook.
Somehow there's no darksage in my environnement. I also tried to modify it to barh because I think vertical bars look better for my data, but my attempts break the index 😭

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.