使用 matplotlib 绘制两个不同大小的列表的问题

Problem with plotting two lists with different sizes using matplotlib

我对 matplotlib 非常陌生,我正在尝试在 python 中创建一个 discord 机器人,它只记录服务器 activity 并将其显示为基于时间的折线图服务器最活跃(每 10 秒消息/一天中的时间)。问题是,一天中 99.99% 的时间消息数量与秒数不同,因此 2 个列表不匹配,我得到

ValueError: x and y must have same first dimension, 

我的列表是这样的:

instances= [(6209, 10), (42906, 20), (70182, 23), (30422, 18), (70503, 21), (8426, 12), (78322, 22), (27038, 17), (1453, 2), (36138, 3)]
times= [0, 3600, 7200, 10800, 14400, 18000, 21600, 25200, 28800, 32400, 36000, 39600, 43200, 46800, 50400, 54000, 57600, 61200, 64800, 68400, 72000, 75600, 79200]

所以我有一个列表(什么时间,多少条消息)和一个以秒为单位的一天中每个小时的列表,所以我可以将它们绘制成 在这个时间发生了这么多条消息天。 我如何将它们绘制到单个图形上,因为 ax.plot (instances, times) 给我错误。我搜索了其他答案,但 none 对我有帮助。

  • 在这种情况下,数据显示为条形图效果更好。
  • instances中提取秒和值以分隔变量
  • 将秒数转换为 H:M:S
  • 的标准时间格式
  • 似乎不​​需要times
import matplotlib.pyplot as plt
import seaborn as sns
from datetime import timedelta

instances= [(6209, 10), (42906, 20), (70182, 23), (30422, 18), (70503, 21), (8426, 12), (78322, 22), (27038, 17), (1453, 2), (36138, 3)]

# separate out x and convert from seconds to H:M:S
x = [timedelta(seconds=v[0]) for v in instances]

# separate out the y values
y = [v[1] for v in instances]

# sort x and y, based on time
x, y = zip(*sorted(zip(x, y)))

# convert from tuples to lists because barplot won't work with tuples
x, y = list(x), list(y)

# plot
fig = plt.figure(figsize=(10, 5))
p = sns.barplot(x=x, y=y)
p.set(xlabel='Observation Time', ylabel='Activity Count', title='Messages')

# annotate
p.bar_label(p.containers[0], label_type='edge', padding=1)

# pad the spacing between the number and the edge of the figure
p.margins(y=0.1)

  • 绘制为线图
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
from datetime import timedelta

instances= [(6209, 10), (42906, 20), (70182, 23), (30422, 18), (70503, 21), (8426, 12), (78322, 22), (27038, 17), (1453, 2), (36138, 3)]

# separate out the x values
x = [v[0] for v in instances]

# separate out the y values
y = [v[1] for v in instances]

# sort x and y, based on time
x, y = zip(*sorted(zip(x, y)))

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

ax.plot(x, y, marker='o')

# fixing xticks with matplotlib.ticker "FixedLocator"
xticks_loc = ax.get_xticks()
ax.xaxis.set_major_locator(mticker.FixedLocator(xticks_loc))
_ = ax.set_xticklabels([timedelta(seconds=tm) for tm in xticks_loc])

  • 如果你想在 x 轴上有更多的时间,而不是使用 ax.get_xticks,传递 list 个值,或使用 range) xticks_loc = range(0, 86400, 3600) 并添加 ax.set_xlim(0, 86400)
  • 大概增加图的宽度fig, ax = plt.subplots(figsize=(15, 5))
  • 旋转 x 轴标签 _ = ax.set_xticklabels([timedelta(seconds=tm) for tm in xticks_loc], rotation=45)
# fixing xticks with matplotlib.ticker "FixedLocator"
ax.set_xlim(0, 86400)

xticks_loc = range(0, 86400, 3600)

ax.xaxis.set_major_locator(mticker.FixedLocator(xticks_loc))
_ = ax.set_xticklabels([timedelta(seconds=tm) for tm in xticks_loc], rotation=45)