简体   繁体   中英

Matplotlib Horizontal Bar Plot (barh): Why are the bars on top and not beside each other?

I am trying to replicate this example, except as a horizontal bar plot.

I wrote this code:

import sys
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.ticker import StrMethodFormatter
import numpy as np

Fams = ['Item1','Item2','Item3','Item4','Item5','Item6','Item7','Item8','Item9','Item10','Item11','Item12','Item13','Item14','Item15','Item16','Item17','Item18','Item19','Item20','Item21']
AllTested = [3,3,3,3,4,4,4,4,4,4,4,5,5,6,6,7,9,9,10,10,27]
BestSubsetTested = [1,0,0,0,3,0,3,0,1,0,1,1,2,4,1,1,8,4,9,8,11]

plt.figure(figsize=[60,40])
X = np.arange(len(Fams))
plt.barh(X,AllTested,color='g')
plt.barh(X + 0.25,BestSubsetTested,color='b')
plt.yticks([i+0.25 for i in range(len(Fams))],Fams)

# Naming the x and y axis
plt.xlabel('Tests')
plt.ylabel('Fams')

plt.savefig('day2.png',format='png')

When I don't add in any width parameter, the script runs, but in the output, the bars are not beside each other:

Since I want the bars to beside each other (ie Fam item has two bars paired together - AllTested and BestSubsetTested -, with a slightly bigger gap between each Fam item to make this clear, similar to example), I added in 'width' parameter as in the example, but I get the error:

I get an error saying:

Traceback (most recent call last):
  File "make_plot_species_multiple2.py", line 13, in <module>
    plt.barh(X,AllTested,color='g',width=0.25)

Can anyone help me?

The final output should look similar to what I made except

  • the bars are in pairs (ie item 1 has two bars, item2 has two bars)

  • the name for each pair of bars should be in the middle of it

  • if you could possibly show me how to tilt the name of each bar 45/make the font bigger so it's more readable that would be great because I shortened the names for this example.

For barh , the width of the bars is controlled by the height argument, not width . Here I set height to 0.4 for both barh calls, and offset them by +/- 0.25. You don't need to offset the yticks if you offset the bars up and down as I do here.

To rotate the tick labels, you can add rotation=45 to the yticks function.

And to make the tick labels bigger, I just reduced the figure size from (60, 40) to (12, 8). An alternative would be to change the fontsize for all the tick labels and axes labels.

import sys
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.ticker import StrMethodFormatter
import numpy as np
plt.rcdefaults()

Fams = ['Item1','Item2','Item3','Item4','Item5','Item6','Item7','Item8','Item9','Item10','Item11','Item12','Item13','Item14','Item15','Item16','Item17','Item18','Item19','Item20','Item21']
AllTested = [3,3,3,3,4,4,4,4,4,4,4,5,5,6,6,7,9,9,10,10,27]
BestSubsetTested = [1,0,0,0,3,0,3,0,1,0,1,1,2,4,1,1,8,4,9,8,11]

plt.figure(figsize=[12, 8])
X = np.arange(len(Fams))
plt.barh(X-0.25, AllTested,color='g', height=0.4)
plt.barh(X+0.25, BestSubsetTested,color='b', height=0.4)
plt.yticks([i for i in range(len(Fams))],Fams, rotation=45)

# Naming the x and y axis
plt.xlabel('Tests')
plt.ylabel('Fams')

plt.savefig('day2.png',format='png')

在此处输入图像描述

import pandas as pd
import matplotlib.pyplot as plt

# using your data to create the dataframe
df = pd.DataFrame({'all_tested': AllTested, 'best_sub_tested': BestSubsetTested}, index=Fams)

# display(df.head())
       all_tested  best_sub_tested
Item1           3                1
Item2           3                0
Item3           3                0
Item4           3                0
Item5           4                3

# plot the dataframe
df.plot.barh(figsize=(16, 8))
plt.ylabel('Fams')
plt.xlabel('Tests')
plt.show()

在此处输入图像描述

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