Горизонтальный линейный график с несколькими барами на ytick - PullRequest
2 голосов
/ 07 апреля 2019

Я не совсем понимаю, как вы должны передавать параметры для создания горизонтальной гистограммы в matplotlib.Я просто пытаюсь подражать тому, что я вижу в этом примере кода ... https://pythonspot.com/matplotlib-bar-chart/

Как и то, что я вижу в этом сообщении stackoverflow Как построить несколько горизонтальных столбцов на одном графике с помощью matplotlib

Прямо сейчас мой код выглядит следующим образом:

import numpy as np
x_locs = np.arange(len(total_vals))
t_label_lst = ['Digital Learning Apps', 'News, Events, Daily', 'News on School Events', 'STEM Extracurriculars & School Programs', 'Hiring, STEM Workforce', 'Women in STEM', 'Activities and Projects Outside of the Classroom', 'Ambiguous', 'Ambiguous, STEM in College', 'Next Generation of Engineers', 'News, Events, Daily', 'Educational Policy and Higher Education, Reform', 'STEM Activities, Building, Arts, and Design', 'Engaging students with STEM using programming and robotics', 'Black Leaders in STEM', 'Next Generation of Engineers', 'Ambiguous', 'Astronomy, NASA', 'STEM workshops and summer camps', 'Competitions, Team Credit', 'Ambiguous, Technology Hashtags', 'Google Education', 'Good Job Today! Crediting Daily Activities and Work', 'Engaging students with STEM using programming and robotics', 'Environmental Science', 'Teachers, Public Schools In STEM', 'Ambiguous', 'Edtech Companies', 'Ambiguous, PHD Conversation', 'Ambiguous', 'Engaging students with STEM using programming and robotics', 'Ambiguous, Virtual Reality and Personalized learning mention', 'Ambiguous', 'Ambiguous', 'Ambiguous, #Autism hashtag has disproportionate weight']

print(x_locs)
total_vals = [23668, 13186, 10752, 10002, 9558, 9126, 8138, 7389, 7006, 6965, 6859, 6621, 6538, 5700, 5110, 5069, 4419, 4025, 3943, 3866, 3761, 3697, 3543, 3294, 3067, 2928, 2511, 2491, 2353, 2312, 2229, 2175, 2021, 1921, 1787]
positive_vals = [9941, 9306, 7595, 5935, 5913, 7488, 5258, 4905, 4026, 5242, 5557, 3225, 3530, 3055, 3300, 3503, 2461, 2199, 2074, 2379, 1665, 2274, 2250, 1674, 1523, 1533, 1241, 859, 1504, 1419, 1132, 1082, 805, 753, 580]
neutral_vals = [13727, 3880, 3157, 4067, 3645, 1638, 2880, 2484, 2980, 1723, 1302, 3396, 3008, 2645, 1810, 1566, 1958, 1826, 1869, 1487, 2096, 1423, 1293, 1620, 1544, 1395, 1270, 1632, 849, 893, 1097, 1093, 1216, 1168, 1207]

rects1 = ax.barh(x_locs, total_vals, width=.15, color='r', label="total tweet count")
# rects2 = ax.barh(positive_vals, width=.2, color = 'b', label="positive tweet count")
# rects3 = ax.barh(neutral_vals, width=.2, color='yellow', label="neutral tweet count")
ax.set(yticks=x_locs, yticklabels=t_label_lst, ylim=[0, len(x_locs)])
plt.show()

Но это просто вызывает сбой программы со следующим сообщением об ошибке: "TypeError: barh () получил несколько значений дляаргумент 'ширина' "Я даже не уверен, почему возникает эта ошибка, если я устанавливаю параметр ширины на .15.

total_vals содержит 35 отсчетов или частот, которые я пытаюсь построить вось х.Например, это те значения, которые я пытаюсь сделать так, чтобы мои столбики отражали высоту.Positive_vals и absolute_vals также содержат 35 отсчетов.

x_locs - это переменная, которую я создал на основе того, что я видел в примере кода, но это просто числа 0-34.Это просто должно указывать на каждый из 35 баров, которые я пытаюсь показать.

Что меня также смущает, так это то, что происходит, когда я удаляю x_locs.Поэтому, если я просто сделаю

 rects1 = ax.barh(total_vals, width=.15, color='r', label="total tweet count")

, я получу этот график matplotlib, который, кажется, отображает мой параметр "width" на оси x графика / делает параметр width пределом оси x.

graph in which the x axis is actually the width parameter. At least my yticks are correct

Мне кажется, что мои yticks действительно правильно отображают в том порядке, в котором они должны быть, по крайней мере, но кажется, что ширина - это то, чтополучение графика или измерение по оси x ... и, очевидно, график пуст.

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

На данный момент я не совсем уверен, что именно параметр "y" должен указывать.В документации написано «y координаты каждой полосы».Сначала я думал, что параметр y должен был быть только тем счетчиком, который я хотел показать, но потом я увидел, что «левый» параметр - это «x координаты левой стороны столбцов».

Поэтому я изменил свой код на

rects1 = ax.barh(y=x_locs, left=total_vals, width=.15, color='r', label="total tweet count")

И это правильно изменило ось y, но все равно дало мне пустой график.Я не знаю, что происходит с моими счетчиками / барами и почему они вообще не отображаются.

yet another empty matplotlib graph but at least the x axis is correct now

Как я могу получить барыпоказывать?У меня просто есть некоторая путаница в отношении того, как на самом деле работают параметры для этих горизонтальных гистограмм.

1 Ответ

2 голосов
/ 07 апреля 2019

Вы действительно были очень близки со своим кодом; у вас просто была путаница с параметрами barh.

Во-первых, давайте уточним обязательные аргументы.

Первый позиционный аргумент - y, который относится к y-координатам каждой категории . Соответственно, x_locs является неправильным. Их можно легко создать в рабочем порядке: первая категория - y=0, вторая - y=1 и т. Д.

Далее вы передаете переменную, например total_vals, но также width, и получаете ошибку.

Учтите, что полоса определяется двумя аспектами: позиция и размер . Поскольку все столбцы выровнены по левому краю графика, их x-координаты одинаковы, и они будут определяться исключительно своими y-координатами, что мы уже сделали.

Для гистограммы мы обычно хотим, чтобы одно измерение было динамическим (то, которое представляет некоторое количество), а другое было одинаковым для всех баров. То же самое, что и height, так как оно равно вертикальному размеру стержня.

Тогда другое, динамическое измерение - это width, и width представляет total_vals, positive_vals и negative_vals. Соответственно, вы получили эту ошибку, потому что пытались указать, как долго каждый бар должен быть дважды .

Теперь вернемся к y_locs. Помните, что мы хотим 3 бара для каждого тика, рядом . Это равносильно тому, что мы хотим, чтобы каждый «класс» баров (total, negative и positive) был немного скорректирован, иначе они перекрываются.

Например, мы могли бы оставить бары для negative в позициях, указанных y_loc, для positive, смещенных вниз на 10 пикселей, а для total на 20. Это детали реализации; важно то, что мы признаем потребность для такого смещения.

Собрав все это вместе, мы получим:

import numpy as np
from matplotlib import pyplot as plt

fig, ax = plt.subplots(figsize=(6, 10))

t_label_lst = ['Digital Learning Apps', 'News, Events, Daily', 'News on School Events', 'STEM Extracurriculars & School Programs', 'Hiring, STEM Workforce', 'Women in STEM', 'Activities and Projects Outside of the Classroom', 'Ambiguous', 'Ambiguous, STEM in College', 'Next Generation of Engineers', 'News, Events, Daily', 'Educational Policy and Higher Education, Reform', 'STEM Activities, Building, Arts, and Design', 'Engaging students with STEM using programming and robotics', 'Black Leaders in STEM', 'Next Generation of Engineers', 'Ambiguous', 'Astronomy, NASA', 'STEM workshops and summer camps', 'Competitions, Team Credit', 'Ambiguous, Technology Hashtags', 'Google Education', 'Good Job Today! Crediting Daily Activities and Work', 'Engaging students with STEM using programming and robotics', 'Environmental Science', 'Teachers, Public Schools In STEM', 'Ambiguous', 'Edtech Companies', 'Ambiguous, PHD Conversation', 'Ambiguous', 'Engaging students with STEM using programming and robotics', 'Ambiguous, Virtual Reality and Personalized learning mention', 'Ambiguous', 'Ambiguous', 'Ambiguous, #Autism hashtag has disproportionate weight']

total_vals = [23668, 13186, 10752, 10002, 9558, 9126, 8138, 7389, 7006, 6965, 6859, 6621, 6538, 5700, 5110, 5069, 4419, 4025, 3943, 3866, 3761, 3697, 3543, 3294, 3067, 2928, 2511, 2491, 2353, 2312, 2229, 2175, 2021, 1921, 1787]
positive_vals = [9941, 9306, 7595, 5935, 5913, 7488, 5258, 4905, 4026, 5242, 5557, 3225, 3530, 3055, 3300, 3503, 2461, 2199, 2074, 2379, 1665, 2274, 2250, 1674, 1523, 1533, 1241, 859, 1504, 1419, 1132, 1082, 805, 753, 580]
neutral_vals = [13727, 3880, 3157, 4067, 3645, 1638, 2880, 2484, 2980, 1723, 1302, 3396, 3008, 2645, 1810, 1566, 1958, 1826, 1869, 1487, 2096, 1423, 1293, 1620, 1544, 1395, 1270, 1632, 849, 893, 1097, 1093, 1216, 1168, 1207]

bar_size = 0.25
padding = 0.25

y_locs = np.arange(len(total_vals)) * (bar_size * 3 + padding)

rects1 = ax.barh(y_locs, total_vals, align='edge', height=bar_size, color='r', label="total tweet count")
rects2 = ax.barh(y_locs + bar_size, positive_vals, align='edge', height=bar_size, color='b', label="positive tweet count")
rects3 = ax.barh(y_locs + 2 * bar_size, neutral_vals, align='edge', height=bar_size, color='yellow', label="neutral tweet count")
ax.set(yticks=x_locs, yticklabels=t_label_lst, ylim=[0 - padding, len(x_locs)])

Output

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...