График горизонтальной линейки Matplotlib (barh): почему столбцы расположены сверху, а не рядом друг с другом?

#python #matplotlib

#python #matplotlib

Вопрос:

Я пытаюсь воспроизвести этот пример, за исключением построения горизонтальной полосы.

Я написал этот код:

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

Когда я не добавляю ни одного параметра width, скрипт запускается, но на выходе полосы не расположены рядом друг с другом:

Поскольку я хочу, чтобы полосы располагались рядом друг с другом (т. Е. элемент Fam имеет две полосы, соединенные вместе — AllTested и BestSubsetTested — , с немного большим промежутком между каждым элементом Fam, чтобы было понятно, аналогично примеру), я добавил параметр ‘width’, как в примере, но я получаю сообщение об ошибке:

Я получаю сообщение об ошибке:

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

Кто-нибудь может мне помочь?

Конечный результат должен выглядеть аналогично тому, что я сделал, за исключением

  • столбцы расположены парами (т. е. элемент 1 имеет два столбца, элемент 2 имеет два столбца)

  • название каждой пары полос должно быть в середине

  • если бы вы могли показать мне, как наклонить название каждой полосы на 45 / увеличить шрифт, чтобы его было удобнее читать, это было бы здорово, потому что я сократил названия для этого примера.

Комментарии:

1. plt.barh(X 0.25,BestSubsetTested,color='b') ширина / высота полос по умолчанию равна 0.8 , так что да, вы бы увидели, что они перекрываются, если просто сдвинуть их на 0.25 .

2. plt.barh(..., height=0.4) может помочь

Ответ №1:

Для barh ширина полос определяется height аргументом, а не width . Здесь я установил height значение 0.4 для обоих barh вызовов и сместил их на /- 0.25. Вам не нужно смещать yticks, если вы смещаете столбцы вверх и вниз, как я делаю здесь.

Чтобы повернуть метки тиков, вы можете добавить их rotation=45 в yticks функцию.

И чтобы увеличить метки тиков, я просто уменьшил размер фигуры с (60, 40) до (12, 8). Альтернативой было бы изменить размер шрифта для всех меток тиков и меток осей.

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

введите описание изображения здесь

Комментарии:

1. Огромное спасибо. Можно ли легко добавить больший пробел между каждым элементом по оси y, чтобы сделать его более четким? Не волнуйтесь, если это сложно, это не было частью исходного вопроса, просто интересно, было ли это быстрым дополнением, чтобы сделать его более читаемым. Спасибо.

2. Если вы имеете в виду пространство между текстовыми метками, я предполагаю, что вы либо хотите уменьшить размер текста, либо изменить угол наклона текста.

Ответ №2:

  • Я рекомендую использовать pandas для работы с табличными данными
  • pandas.DataFrame.plot упрощает создание столбчатых графиков из нескольких столбцов данных.
  • Когда данные находятся в pandas, их также легче анализировать
 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()
  

введите описание изображения здесь