简体   繁体   中英

Matplotlib stacked bar chart

Hi I'm fairly new to matplotlib but I'm trying to plot a stacked bar chart. Instead of stacking, my bars are overlapping one another.

This is the dictionary where I'm storing data.

eventsDict = {
'A' : [30.427007371788505, 3.821656050955414], 
'B' : [15.308879925288613, 25.477707006369428], 
'C' : [10.846066723627477, 1.910828025477707], 
'D' : [0.32586881793073297, 0.6369426751592357],
'E' : [3.110656307747332, 11.464968152866243], 
'F' : [8.183480040534901, 1.910828025477707], 
'G' : [3.048065650644783, 16.560509554140125], 
'H' : [9.950920976811652, 4.45859872611465]
}

My stacked bar graph has two bars. The first one contains all the data from the first value of the list and the second one contains all the second values from the list. (The list being the values in the dictionary)

First, I convert the dictionary to a tuple:

allEvents = list(self.eventsDict.items()) 

This turns the dictionary to this list:

all Events = [('A', [30.427007371788505, 3.821656050955414]), ('B', [15.308879925288613, 25.477707006369428]), ('C', [10.846066723627477, 1.910828025477707]), ('D', [0.32586881793073297, 0.6369426751592357]), ('E', [3.110656307747332, 11.464968152866243]), ('F', [8.183480040534901, 1.910828025477707]), ('G', [3.048065650644783, 16.560509554140125]), ('H', [9.950920976811652, 4.45859872611465])]

This is where I plot it:

    range_vals = np.linspace(0, 2, 3)
    mid_vals = (range_vals[0:-1] + range_vals[1:]) * 0.5
        colors = ['#DC7633', '#F4D03F', '#52BE80', '#3498DB', '#9B59B6', '#C0392B', '#2471A3', '#566573', '#95A5A6']
        x_label = ['All events. %s total events' % (totalEvents), 'Corrected p-value threshold p < %s. %s total events' % (self.pVal, totalAdjusted)]

    #Turn the dict to a tuple. That way it is ordered and is subscriptable.
    allEvents = list(self.mod_eventsDict.items())
    #print (allEvents)

    #Use below to index:
    #list[x] key - value pairing
    #list[x][0] event name (key)
    #list[x][1] list of values [val 1(all), val 2(adjusted)]

    #Plot the Top bar first
    plt.bar(mid_vals, allEvents[0][1], color = colors[0], label = allEvents[0][0])

    #Plot the rest
    x = 1
    for x in range(1, 20):
        try:
            plt.bar(mid_vals, allEvents[x-1][1], bottom =allEvents[x-1][1], color = colors[x], label = allEvents[x][0])           
            x = x + 1
        except IndexError:
            continue


    plt.xticks(mid_vals) # for classic style
    plt.xticks(mid_vals, x_label) # for classic style

    plt.xlabel('values')
    plt.ylabel('Count/Fraction')
    plt.title('Stacked Bar chart')
    plt.legend()
    plt.axis([0, 2.5, 0, 1])
    plt.show()

This is the graph output. Ideally, they should all add up to 1 when stacked. I made them all a fraction of one whole so that both bars will have the same height. However, they just overlap each other. Also, note that stacks have a different label from their names on the dictionary.

堆叠条形图输出

Please help me debug!!

You'll need to set bottom differently - this tells matplotlib where to place the bottom of the bar you're plotting, so it needs to be the sum of all of the heights of the bars that came before.

You could for example track the current heights of the bars with a list like so:

current_heights = [0] * 20
for x in range(20):
    try:
        plt.bar(mid_vals, allEvents[x][1], bottom=current_heights[x], color=colors[x], label=allEvents[x][0])           
        x = x + 1
        current_heights[x] += allEvents[x][1] #increment bar height after plotting
    except IndexError:
        continue

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM