python - 每个 ytick 有多个条形的水平条形图

标签 python matplotlib

我不太明白你应该如何传递参数来在 matplotlib 中创建水平条形图。我只是想模仿我在这个示例代码中看到的内容... https://pythonspot.com/matplotlib-bar-chart/

以及我在 stackoverflow 帖子中看到的内容 How to plot multiple horizontal bars in one chart with 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() gets multiple values for argument 'width'” 我什至不确定为什么会出现此错误,如果我设置宽度参数设置为 0.15。

total_vals 包含 35 个计数,或我尝试在 x 轴上绘制的频率。就像这些是我试图让我的条形反射(reflect)高度的值。 Positive_vals 和中性_vals 也包含 35 个计数。

x_locs 是我根据示例代码中看到的内容创建的变量,但它应该是数字 0-34。这只是应该指示我要显示的 35 个条中的每一个。

同样让我困惑的是当我删除 x_locs 时会发生什么。所以如果我这样做

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

我得到了这个matplotlib图表,它似乎在图表的x轴上绘制了我的“宽度”参数/使宽度参数成为x轴的限制。

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

我的 yticks 似乎实际上按照至少应有的顺序正确显示,但宽度似乎是在 x 轴上绘制或测量的......显然,图表是空的.

我发现我的 yticklabels 现在太长了,我只是上传了这段代码,以便它可以重现。

此时我不太确定“y”参数实际上应该表示什么。文档说“每个条形的 y 坐标”。我最初认为 y 参数应该是我想要显示的计数,但后来我看到“left”参数是“条形左侧的 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

我如何才能真正显示条形图?我只是对这些水平条形图的参数实际如何工作有一些明显的困惑。

最佳答案

您实际上非常熟悉您的代码;您只是对 barh 的参数有些困惑.

首先,让我们澄清所需的参数。

第一个位置参数是 y ,它指的是每个类别的 y 坐标。因此,x_locs是用词不当。这些可以按运行顺序轻松创建:第一个类别位于 y=0 ,第二个位于 y=1等等。

接下来,您传递一个变量,如 total_vals ,还有width ,并出现错误。

考虑一个条形由两个方面定义:位置大小。由于所有条形图都与图的左脊柱对齐,因此它们的 x 坐标相同,并且它们将仅由 y 坐标定义,我们已经完成了这一点。

对于条形图,我们通常希望一个维度是动态的(表示某个数量的维度),而另一个维度对于所有条形而言都是相同的。相同的是height ,因为它等于条形的垂直尺寸。

另一个动态维度是 width ,它是 width代表total_vals , positive_valsnegative_vals 。因此,您收到该错误是因为您试图指定每个条的长度应两次

现在,让我们回到 y_locs 。请记住,我们希望每个价格变动有 3 个柱,并排。这相当于说我们希望条形图的每个“类”( totalnegativepositive )稍微调整,否则它们会重叠。

例如,我们可以使用 negative 的条形图。保留在 y_loc 指定的位置, positivetotal 向下移动 10 个像素到 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

关于python - 每个 ytick 有多个条形的水平条形图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55554459/

相关文章:

python - 如何从python中的stdin逐行读取

python - 用于计算 DNA 序列中 GC 含量的初级 Python 脚本

python - 设置默认透明度 savefig

python - 如何在直方图上绘制高斯分布

python - 在绘图上显示数据框

python - 当 Chrome 浏览器工作时,Web Scraper 返回空的 html 文件;已经尝试过 UserAgent

python - 循环导入的函数中的模块导入会循环导入吗?

python - 如何通过 Python Azure SDK 了解 Azure blob 对象的大小

Python 图像教程有效,其他图像表现不同(使用 Pylab 显示图像)

python - Matplotlib set_data使我的程序卡住(请检查 'Updated issue')