[英]How can a plot a 5 grouped bars bar chart in matplotlib?
我有以下數據框:
meteo = [["January", 9.2, 13.6, 4.7, 37, 70],
["February",9.9, 14.3, 5.4, 35, 70],
["March", 11.8, 16.1, 7.4, 36, 70],
["April", 13.7, 18.0, 9.4, 40, 69],
["May", 16.9, 21.1, 12.8, 47, 70],
["June", 20.9, 24.9, 16.8, 30, 68],
["July", 23.9, 28.0, 19.8, 21, 67],
["August", 24.4, 28.5, 20.2, 62, 68],
["September", 21.7, 26.0, 17.4, 81, 70],
["October", 17.8, 22.1, 13.5, 91, 73],
["November", 13.0, 17.3, 8.6, 59, 71],
["December", 10.0, 14.3, 5.7, 40, 69]]
import pandas as pd
# Create dataframe with above data
df = pd.DataFrame(meteo)
# Drop useless column
df.drop(0, inplace = True, axis = 1)
# Rename columns
df.rename(columns = {1: "Temp_media_anual_mes", 2: "Temp_máxima_media", 3: "Temp_mínima_media", 4: "Media_lluvias_mensual", 5:"Humedad_media_rel"}, inplace = True)
df["mes"] = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
現在,我想繪制一個分組條形圖。 我想每月有 5 個分組酒吧。 我試過這個,但我對條之間的空間有一點問題:
# Setting the positions and width for the bars
pos = list(range(len(df.mes)))
width = 0.25
# Plotting the bars
fig, ax = plt.subplots(figsize=(16,10))
# Create a bar with pre_score data,
# in position pos,
plt.bar(pos,
#using df['pre_score'] data,
df['Temp_media_anual_mes'],
# of width
width,
# with alpha 0.5
alpha=0.5,
# with color
color='red')
# with label the first value in first_name
#label=df['first_name'][0])
# Create a bar with mid_score data,
# in position pos + some width buffer,
plt.bar([p + width for p in pos],
#using df['mid_score'] data,
df['Temp_máxima_media'],
# of width
width,
# with alpha 0.5
alpha=0.5,
# with color
color='green')
# with label the second value in first_name
#label=df['first_name'][1])
# Create a bar with post_score data,
# in position pos + some width buffer,
plt.bar([p + width*2 for p in pos],
#using df['post_score'] data,
df['Temp_mínima_media'],
# of width
width,
# with alpha 0.5
alpha=0.5,
# with color
color='blue')
# with label the third value in first_name
#label=df['first_name'][2])
plt.bar([p + width*2 for p in pos],
#using df['post_score'] data,
df['Media_lluvias_mensual'],
# of width
width,
# with alpha 0.5
alpha=0.5,
# with color
color='orange')
# with label the third value in first_name
#label=df['first_name'][2])
plt.bar([p + width*2 for p in pos],
#using df['post_score'] data,
df['Humedad_media_rel'],
# of width
width,
# with alpha 0.5
alpha=0.5,
# with color
color='purple')
# with label the third value in first_name
#label=df['first_name'][2])
# Set the y axis label
ax.set_ylabel('Amount')
# Set the chart's title
ax.set_title('Rain and temperature')
# Set the position of the x ticks
ax.set_xticks([p + 1.5 * width for p in pos])
# Set the labels for the x ticks
ax.set_xticklabels(df['mes'])
# Setting the x-axis and y-axis limits
plt.xlim(min(pos)-width, max(pos)+width*4)
plt.ylim([0, max(df['Temp_media_anual_mes'] + df['Temp_máxima_media'] + df['Temp_mínima_media'] + df["Media_lluvias_mensual"] + df["Humedad_media_rel"])] )
plt.grid()
plt.show()
這是我得到的情節
如您所見,它顯示了 3 個獨立的條形,在第三個中,有 3 個條形一個接一個。 我知道問題出在條形之間的間距上,但我不知道如何解決。 有人能指出我正確的方向嗎?
編輯:
我還想在每個條形上方顯示每個繪制值的測量單位。 這些是:
非常感謝您提前
這是一些放置條形的代碼,將月份名稱居中,...
請注意,ylim 的原始計算是錯誤的,它不應該是最大值的總和,而是最大值的最大值。 我還添加了一些帶有列上方單位的文本。 我試圖找到一些合適的顏色:紅黃色代表溫度,藍色代表雨,藍綠色代表濕度。
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
meteo = [["January", 9.2, 13.6, 4.7, 37, 70],
["February", 9.9, 14.3, 5.4, 35, 70],
["March", 11.8, 16.1, 7.4, 36, 70],
["April", 13.7, 18.0, 9.4, 40, 69],
["May", 16.9, 21.1, 12.8, 47, 70],
["June", 20.9, 24.9, 16.8, 30, 68],
["July", 23.9, 28.0, 19.8, 21, 67],
["August", 24.4, 28.5, 20.2, 62, 68],
["September", 21.7, 26.0, 17.4, 81, 70],
["October", 17.8, 22.1, 13.5, 91, 73],
["November", 13.0, 17.3, 8.6, 59, 71],
["December", 10.0, 14.3, 5.7, 40, 69]]
df = pd.DataFrame(meteo)
#df.rename(columns = {0:"mes", 1: "Temp. media mes", 2: "Temp. máxima media", 3: "Temp. mínima media", 4: "Media lluvias mensual", 5:"Humedad media rel"}, inplace = True)
df.rename(columns = {0:"month", 1: "Mean monthly temperature", 2: "Max. monthly temperature", 3: "Min. monthly temperature", 4: "Mean monthly rainfall", 5:"Mean relative humidity"}, inplace = True)
# Setting the positions and width for the bars
pos = list(range(len(df)))
num_col = len(df.columns) - 1
width = 0.95 / num_col
fig, ax = plt.subplots(figsize=(16,10))
bar_colors = ['#feb24c', '#f03b20', '#ffeda0', '#43a2ca', '#a8ddb5']
bar_labels = df.columns[1:]
for i, (colname, color, lbl) in enumerate(zip(df.columns[1:], bar_colors, bar_labels)):
delta_p = 0.125 + width*i
plt.bar([p + delta_p for p in pos],
df[colname], width, color=color, label=lbl)
for j in range(len(df)):
ax.annotate("°C" if i < 3 else "mm" if i == 3 else "%",
xy=(pos[j] + delta_p, df[colname][j] + 1),
ha='center')
ax.set_ylabel('Amount')
ax.set_title('Temperatures, Rain and Humidity')
ax.set_xticks(pos)
def update_ticks(x, pos):
return df['month'][pos]
ax.xaxis.set_major_formatter(ticker.NullFormatter())
ax.xaxis.set_minor_formatter(ticker.FuncFormatter(update_ticks))
ax.xaxis.set_minor_locator(ticker.FixedLocator([p+0.5 for p in pos]))
for tick in ax.xaxis.get_minor_ticks():
tick.tick1line.set_markersize(0)
tick.tick2line.set_markersize(0)
tick.label1.set_horizontalalignment('center')
plt.xlim(min(pos), max(pos)+1)
plt.ylim([0, 10+max([max(df[colname]) for colname in df.columns[1:]])])
plt.legend()
plt.grid()
plt.show()
你不需要那么多的情節調用。 你可以一次性完成。
>>> ax = df.plot.bar(x='mes', y=list(df.columns[1:6]))
>>> plt.show()
關於在每個條形上方顯示值,您可以參考這篇文章,其中我解釋了如何將文本添加到直方圖的頂部。 您也可以對條形圖執行相同的操作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.