How to plot bar graphs with same X coordinates side by side ('dodged')

后端 未结 5 1858
慢半拍i
慢半拍i 2020-12-05 02:12
import matplotlib.pyplot as plt

gridnumber = range(1,4)

b1 = plt.bar(gridnumber, [0.2, 0.3, 0.1], width=0.4,
                label=\"Bar 1\", align=\"center\")

b2         


        
相关标签:
5条回答
  • 2020-12-05 02:43

    There is an example in the matplotlib site. Basically, you just shift the x values by width. Here is the relevant bit:

    import numpy as np
    import matplotlib.pyplot as plt
    
    N = 5
    menMeans = (20, 35, 30, 35, 27)
    menStd =   (2, 3, 4, 1, 2)
    
    ind = np.arange(N)  # the x locations for the groups
    width = 0.35       # the width of the bars
    
    fig = plt.figure()
    ax = fig.add_subplot(111)
    rects1 = ax.bar(ind, menMeans, width, color='royalblue', yerr=menStd)
    
    womenMeans = (25, 32, 34, 20, 25)
    womenStd =   (3, 5, 2, 3, 3)
    rects2 = ax.bar(ind+width, womenMeans, width, color='seagreen', yerr=womenStd)
    
    # add some
    ax.set_ylabel('Scores')
    ax.set_title('Scores by group and gender')
    ax.set_xticks(ind + width / 2)
    ax.set_xticklabels( ('G1', 'G2', 'G3', 'G4', 'G5') )
    
    ax.legend( (rects1[0], rects2[0]), ('Men', 'Women') )
    
    plt.show()
    
    0 讨论(0)
  • 2020-12-05 02:43

    Here are two examples of creating a side-by-side bar chart when you have more than two "categories" in a group.

    Manual Method

    Manually set the position and width of each bar.

    import numpy as np
    import matplotlib.pyplot as plt
    from matplotlib import ticker
    
    coins = ['penny', 'nickle', 'dime', 'quarter']
    worth = np.array([.01, .05, .10, .25])
    
    # Coin values times *n* coins
    #    This controls how many bars we get in each group
    values = [worth*i for i in range(1,6)]
    
    n = len(values)                # Number of bars to plot
    w = .15                        # With of each column
    x = np.arange(0, len(coins))   # Center position of group on x axis
    
    for i, value in enumerate(values):
        position = x + (w*(1-n)/2) + i*w
        plt.bar(position, value, width=w, label=f'{i+1}x')
    
    plt.xticks(x, coins);
    
    plt.ylabel('Monetary Value')
    plt.gca().yaxis.set_major_formatter(ticker.FormatStrFormatter('$%.2f'))
    
    plt.legend()
    


    Pandas Method

    If you put the data into a pandas DataFrame, pandas will do the hard stuff for you.

    import pandas as pd
    coins = ['penny', 'nickle', 'dime', 'quarter']
    worth = [0.01, 0.05, 0.10, 0.25]
    df = pd.DataFrame(worth, columns=['1x'], index=coins)
    df['2x'] = df['1x'] * 2 
    df['3x'] = df['1x'] * 3 
    df['4x'] = df['1x'] * 4 
    df['5x'] = df['1x'] * 5 
    

    from matplotlib import ticker
    import matplotlib.pyplot as plt
    
    df.plot(kind='bar')
    
    plt.ylabel('Monetary Value')
    plt.gca().yaxis.set_major_formatter(ticker.FormatStrFormatter('$%.2f'))
    plt.gca().xaxis.set_tick_params(rotation=0)
    

    Pandas creates a similar figure...

    0 讨论(0)
  • 2020-12-05 02:55

    You should convert the x data as numpyarray. enter image description here

    0 讨论(0)
  • 2020-12-05 03:02

    Sometimes could be tricky to find the right bar width. I usually use this np.diff to find the right dimension.

    import numpy as np
    import matplotlib.pyplot as plt
    
    #The data
    womenMeans = (25, 32, 34, 20, 25)
    menMeans = (20, 35, 30, 35, 27)
    indices = [5.5,6,7,8.5,8.9]
    #Calculate optimal width
    width = np.min(np.diff(indices))/3
    
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.bar(indices-width,womenMeans,width,color='b',label='-Ymin')
    ax.bar(indices,menMeans,width,color='r',label='Ymax')
    ax.set_xlabel('Test histogram')
    plt.show()
    

    This is the result:

    What if my indices on my x axis are nominal values like names:

    #
    import numpy as np
    import matplotlib.pyplot as plt
    
    # The data
    womenMeans = (25, 32, 34, 20, 25)
    menMeans = (20, 35, 30, 35, 27)
    indices = range(len(womenMeans))
    names = ['Asian','European','North Amercian','African','Austrailian','Martian']
    # Calculate optimal width
    width = np.min(np.diff(indices))/3.
    
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.bar(indices-width/2.,womenMeans,width,color='b',label='-Ymin')
    ax.bar(indices+width/2.,menMeans,width,color='r',label='Ymax')
    #tiks = ax.get_xticks().tolist()
    ax.axes.set_xticklabels(names)
    ax.set_xlabel('Test histogram')
    plt.show()
    
    0 讨论(0)
  • 2020-12-05 03:07

    Below answer will explain each and every line of code in the simplest manner possible:

    # Numbers of pairs of bars you want
    N = 3
    
    # Data on X-axis
    
    # Specify the values of blue bars (height)
    blue_bar = (23, 25, 17)
    # Specify the values of orange bars (height)
    orange_bar = (19, 18, 14)
    
    # Position of bars on x-axis
    ind = np.arange(N)
    
    # Figure size
    plt.figure(figsize=(10,5))
    
    # Width of a bar 
    width = 0.3       
    
    # Plotting
    plt.bar(ind, blue_bar , width, label='Blue bar label')
    plt.bar(ind + width, orange_bar, width, label='Orange bar label')
    
    plt.xlabel('Here goes x-axis label')
    plt.ylabel('Here goes y-axis label')
    plt.title('Here goes title of the plot')
    
    # xticks()
    # First argument - A list of positions at which ticks should be placed
    # Second argument -  A list of labels to place at the given locations
    plt.xticks(ind + width / 2, ('Xtick1', 'Xtick3', 'Xtick3'))
    
    # Finding the best position for legends and putting it
    plt.legend(loc='best')
    plt.show()
    

    0 讨论(0)
提交回复
热议问题