使用 ax.bar() 使用 matplotlib 绘制多个条形图
Posted
技术标签:
【中文标题】使用 ax.bar() 使用 matplotlib 绘制多个条形图【英文标题】:Plotting multiple bars with matplotlib using ax.bar() 【发布时间】:2019-09-28 07:16:57 【问题描述】:跟进我之前的问题:Sorting datetime objects by hour to a pandas dataframe then visualize to histogram
我需要为一个代表观众人数的 X 轴值绘制 3 个条形图。现在他们显示不到一分钟及以上的内容。我需要一个显示整体观众。我有数据框,但我似乎无法让它们看起来正确。只有 2 条我没有问题,看起来就像我想要有两条条一样:
代码的相关部分:
# Time and date stamp variables
allviews = int(df['time'].dt.hour.count())
date = str(df['date'][0].date())
hours = df_hist_short.index.tolist()
hours[:] = [str(x) + ':00' for x in hours]
我用来表示 X 轴的小时变量可能有问题,因为我将它转换为字符串,所以我可以使小时看起来像 23:00
而不仅仅是熊猫索引输出 23
等。我有看到人们从 X 中添加或减去值以更改条形位置的示例。
fig, ax = plt.subplots(figsize=(20, 5))
short_viewers = ax.bar(hours, df_hist_short['time'], width=-0.35, align='edge')
long_viewers = ax.bar(hours, df_hist_long['time'], width=0.35, align='edge')
现在我设置align='edge'
,两个宽度值是绝对值和负值。但我不知道如何使它看起来与 3 条正确。我没有找到任何关于酒吧的定位论据。我也尝试使用 plt.hist() 但我无法获得与 plt.bar() 函数相同的输出。
因此,我希望在上图左侧显示第三条,比其他两条宽一点。
【问题讨论】:
“我没有找到任何条形定位参数。” - 这是因为您可以完全控制第一个参数(您的hours
)中柱的位置。与 Excel 之类的东西相比,这似乎是一个奇怪的麻烦,直到您尝试在 Excel 中创建一个间距不均匀且条宽不等的条形图:/
【参考方案1】:
pandas
将为您完成此对齐,如果您一步制作条形图而不是两个(或三个)。考虑这个例子(改编自docs,为每只动物添加第三条)。
import pandas as pd
import matplotlib.pyplot as plt
speed = [0.1, 17.5, 40, 48, 52, 69, 88]
lifespan = [2, 8, 70, 1.5, 25, 12, 28]
height = [1, 5, 20, 3, 30, 6, 10]
index = ['snail', 'pig', 'elephant',
'rabbit', 'giraffe', 'coyote', 'horse']
df = pd.DataFrame('speed': speed,
'lifespan': lifespan,
'height': height, index=index)
ax = df.plot.bar(rot=0)
plt.show()
【讨论】:
感谢您为我指明方向!实际上我昨天已经尝试过几次文档中的这个例子,但现在你向我保证这是方向,所以我更加努力了。问题很明显,这个简单实用的解决方案在我将数据帧切片转换为列表后起作用。【参考方案2】:在纯 matplotlib 中,您可以调整绘图的 x 值,而不是使用宽度参数来定位条形:
import numpy as np
import matplotlib.pyplot as plt
# Make some fake data:
n_series = 3
n_observations = 5
x = np.arange(n_observations)
data = np.random.random((n_observations,n_series))
# Plotting:
fig, ax = plt.subplots(figsize=(20,5))
# Determine bar widths
width_cluster = 0.7
width_bar = width_cluster/n_series
for n in range(n_series):
x_positions = x+(width_bar*n)-width_cluster/2
ax.bar(x_positions, data[:,n], width_bar, align='edge')
在您的特定情况下,seaborn 可能是一个不错的选择。您应该(几乎总是)尝试将您的数据保存在long-form 中,因此与其将三个单独的数据框分别用于短、中和长,不如保留一个数据框并添加一个将每一行标记为短的列,中或长。将此新列用作 Seaborn 的 barplot
中的 hue
参数
【讨论】:
感谢 Dan 也跟进这个问题,非常感谢!我刚刚养成了使用 pandas 来处理所有事情的习惯,我正在努力学习语法,所以我会在数据帧而不是纯 python 中提出解决方案。 :) Pandas 很棒,只是不要不必要地拆分您的 DataFrame。 Seaborn 与熊猫配合得很好。最后,除非您想对图表的外观进行大量控制,否则您可能没有理由坚持使用纯 matplotlib 方法。以上是关于使用 ax.bar() 使用 matplotlib 绘制多个条形图的主要内容,如果未能解决你的问题,请参考以下文章