【问题标题】:How to plot bar graphs with same X coordinates side by side ('dodged')如何并排绘制具有相同 X 坐标的条形图(“躲避”)
【发布时间】:2012-05-09 07:49:41
【问题描述】:
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 = plt.bar(gridnumber, [0.3, 0.2, 0.2], color="red", width=0.4,
                label="Bar 2", align="center")


plt.ylim([0,0.5])
plt.xlim([0,4])
plt.xticks(gridnumber)
plt.legend()
plt.show()

目前 b1 和 b2 相互重叠。我如何像这样单独绘制它们:

【问题讨论】:

    标签: python matplotlib bar-chart


    【解决方案1】:

    matplotlib 站点中有一个example。基本上,您只需将x 值移动width。以下是相关位:

    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()
    

    【讨论】:

    • 你能解释一下 yerr 参数是做什么的吗?
    【解决方案2】:

    有时可能很难找到合适的条形宽度。我通常使用这个np.diff 来找到合适的维度。

    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)
    # matplotlib 3.0 you have to use align
    ax.bar(indices-width,womenMeans,width,color='b',label='-Ymin',align='edge')
    ax.bar(indices,menMeans,width,color='r',label='Ymax',align='edge')
    
    
    ax.set_xlabel('Test histogram')
    plt.show()
    # matplotlib 2.0 (you could avoid using align)
    # ax.bar(indices-width,womenMeans,width,color='b',label='-Ymin')
    # ax.bar(indices,menMeans,width,color='r',label='Ymax')
    

    这是结果:

    如果我在 x 轴上的索引是名义值(如名称)怎么办:

    #
    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()
    

    【讨论】:

    • 您好,我喜欢您的回答。如果我在 x 轴上的索引是名义值(如名称)怎么办。
    • @Leokins 您可以更改刻度标签并使用名称而不是数字...查看编辑的 vetdion
    • 第一个对我不起作用,由于某种原因,条形图被移动(没有 x 偏移量的条形图以值为中心,与答案中的帖子不同)。
    • @Vincenzooo 非常感谢你必须使用 matplotlib 3.0 中的评论,align='edge' 查看更新答案
    【解决方案3】:

    下面的答案将以最简单的方式解释每一行代码:

    # 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()
    

    【讨论】:

      【解决方案4】:

      以下是在组中有两个以上“类别”时创建并排条形图的两个示例。

      手动方法

      手动设置每个条的位置和宽度。

      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 DataFrame,pandas 会为您完成困难的工作。

      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)
      

      熊猫创造了一个类似的人物...

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-14
        • 1970-01-01
        相关资源
        最近更新 更多