簡體   English   中英

每個 ytick 具有多個條形的水平條形圖

[英]Horizontal bar plot with multiple bars per ytick

我不太明白您應該如何傳入參數以在 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 個計數,或我試圖在 x 軸上繪制的頻率。 就像這些是我試圖讓我的條形反映高度的值。 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 軸的限制。

x 軸實際上是寬度參數的圖形。至少我的yticks是正確的

我的 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 軸,但它仍然給了我一個空圖。 我不知道我的計數/條發生了什么,以及為什么它們根本不顯示。

另一個空的 matplotlib 圖,但至少 x 軸現在是正確的

我如何真正讓酒吧顯示? 我只是對這些水平條形圖的參數實際工作方式有一些明顯的困惑。

您實際上非常了解您的代碼; 你只是對barh的參數有些困惑。

首先,讓我們澄清所需的參數。

第一個位置參數是y ,它指的是每個 category的 y 坐標。 因此, x_locs是用詞不當。 這些可以很容易地按運行順序創建: y=0處的第一個類別, y=1處的第二個類別,依此類推。

接下來,您傳遞一個變量,如total_valswidth ,並得到一個錯誤。

考慮到一個 bar 是由兩個方面定義的, positionsize 由於所有條形都與繪圖的左側脊線對齊,因此它們的 x 坐標相同,並且它們將僅由它們的 y 坐標定義,我們已經這樣做了。

對於條形圖,我們通常希望一個維度是動態的(代表某個數量的維度),而另一個維度對於所有條形都相同。 相同的是height ,因為它等於條的垂直大小。

另一個動態維度是width ,它是width表示total_valspositive_valsnegative_vals 因此,您收到該錯誤是因為您試圖指定每個條應該有多長兩次

現在,讓我們回到y_locs 請記住,我們希望每個刻度線有 3 個並排的柱線 這相當於說我們希望對 bar 的每個“類”( totalnegativepositive )進行輕微調整,否則它們會重疊。

例如,我們可以讓negative的柱保持在y_loc指定的位置, positivey_loc向下移動 10 個像素, totaly_loc向下移動 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)])

輸出

我認為簡單的答案就是將width更改為height ,因為它是一個垂直圖。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM