setting spacing between grouped bar plots in matplotlib

前端 未结 3 1515
说谎
说谎 2020-12-08 05:53

I\'m trying to make a grouped bar plot in matplotlib, following the example in the gallery. I use the following:

import matplotlib.pyplot as plt
plt.figure(f         


        
相关标签:
3条回答
  • 2020-12-08 06:31

    Actually I think this problem is best solved by adjusting figsize and width; here is my output with figsize=(2,7) and width=0.3:

    enter image description here

    By the way, this type of thing becomes a lot simpler if you use pandas wrappers (i've also imported seaborn, not necessary for the solution, but makes the plot a lot prettier and more modern looking in my opinion):

    import pandas as pd        
    import seaborn 
    seaborn.set() 
    
    df = pd.DataFrame(groups, index=group_labels)
    df.plot(kind='bar', legend=False, width=0.8, figsize=(2,5))
    plt.show()
    

    enter image description here

    0 讨论(0)
  • 2020-12-08 06:31

    I read an answer that Paul Ivanov posted on Nabble that might solve this problem with less complexity. Just set the index as below. This will increase the spacing between grouped columns.

    ind = np.arange(0,12,2)
    
    0 讨论(0)
  • 2020-12-08 06:40

    The trick to both of your questions is understanding that bar graphs in Matplotlib expect each series (G1, G2) to have a total width of "1.0", counting margins on either side. Thus, it's probably easiest to set margins up and then calculate the width of each bar depending on how many of them there are per series. In your case, there are two bars per series.

    Assuming you left align each bar, instead of center aligning them as you had done, this setup will result in series which span from 0.0 to 1.0, 1.0 to 2.0, and so forth on the x-axis. Thus, the exact center of each series, which is where you want your labels to appear, will be at 0.5, 1.5, etc.

    I've cleaned up your code as there were a lot of extraneous variables. See comments within.

    import matplotlib.pyplot as plt
    import numpy as np
    
    plt.figure(figsize=(7,7), dpi=300)
    
    groups = [[1.04, 0.96],
              [1.69, 4.02]]
    group_labels = ["G1", "G2"]
    num_items = len(group_labels)
    # This needs to be a numpy range for xdata calculations
    # to work.
    ind = np.arange(num_items)
    
    # Bar graphs expect a total width of "1.0" per group
    # Thus, you should make the sum of the two margins
    # plus the sum of the width for each entry equal 1.0.
    # One way of doing that is shown below. You can make
    # The margins smaller if they're still too big.
    margin = 0.05
    width = (1.-2.*margin)/num_items
    
    s = plt.subplot(1,1,1)
    for num, vals in enumerate(groups):
        print "plotting: ", vals
        # The position of the xdata must be calculated for each of the two data series
        xdata = ind+margin+(num*width)
        # Removing the "align=center" feature will left align graphs, which is what
        # this method of calculating positions assumes
        gene_rects = plt.bar(xdata, vals, width)
    
    
    # You should no longer need to manually set the plot limit since everything 
    # is scaled to one.
    # Also the ticks should be much simpler now that each group of bars extends from
    # 0.0 to 1.0, 1.0 to 2.0, and so forth and, thus, are centered at 0.5, 1.5, etc.
    s.set_xticks(ind+0.5)
    s.set_xticklabels(group_labels)
    

    Output from my code.

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