时间戳重叠matplotlib

aurhwmvo  于 2022-11-24  发布在  其他
关注(0)|答案(4)|浏览(183)

我尝试使用matplotlib创建一个图表,其中包含请求数(y轴)与时间戳(x轴,HH:MM格式)。该图表将显示上午6:00到下午6:00之间收到的所有请求的模式。以下是示例数据。实际数据超过500个条目。

time_stamp = ['06:02', '06:03', '06:12', '06:16', '06:17', '06:27', '06:28', '06:30', '06:31', '06:34', '06:35', '06:36', '06:37', '06:38', '06:39', '06:40', '06:41', '06:42', '06:43']
requests = [74, 20, 2, 1, 11, 9, 34, 3, 5, 4, 28, 77, 75, 73, 122, 99, 170, 79, 44, 79, 100, 58, 104, 84, 77, 98, 27]

下面是我用来生成图形的脚本。我目前面临的问题是x轴上所有时间戳的重叠。

    • 脚本:**
import matplotlib.pyplot as plt

TITLE = 'Time (Per Minute) Vs Num of Requests Graph'

X_AXIS_NAME = 'TimeStamps (per minute)'
Y_AXIS_NAME = 'No. of Requests'

time_stamp = ['06:02', '06:03', '06:12', '06:16', '06:17', '06:27', '06:28', 
              '06:30', '06:31', '06:34', '06:35', '06:36', '06:37', '06:38', '06:39', 
              '06:40', '06:41', '06:42', '06:43', '06:44', '06:45', '06:46', '06:47', 
              '06:48', '06:49', '06:50', '06:51', '06:52', '06:53', '06:54', '06:55', 
              '06:56', '06:57', '06:58', '06:59', '07:00', '07:01']

requests = [74, 20, 2, 1, 11, 9, 34, 3, 5, 4, 28, 77, 75, 73]

fig, ax = plt.subplots()
plt.plot(time_stamp, requests)
fig.autofmt_xdate()
plt.xlabel(X_AXIS_NAME)
plt.ylabel(Y_AXIS_NAME)
plt.title(TITLE)
plt.show()
fig.savefig('graph.png', dpi=fig.dpi)
    • 生成的图形:**

这是我真正想要生成的图表。这个图表是用Excel生成的。

    • 预期图形:**

时间戳不重叠。

    • 编辑1:**
dates = []
for ts in time_stamp:
    dates.append( datetime.strptime(ts, '%H:%M'))
mp_dates = matplotlib.dates.date2num(dates)
matplotlib.pyplot.plot_date(mp_dates, requests)
    • 编辑2:**
dates = []
for ts in time_stamp:
    local_d = datetime.strptime(ts, '%H:%M')
    dates.append( local_d)

fig, ax = plt.subplots()
plt.setp( ax.xaxis.get_majorticklabels(), rotation=90)
plt.plot(dates, requests)
ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))
#fig.autofmt_xdate()
plt.xlabel(X_AXIS_NAME)
plt.ylabel(Y_AXIS_NAME)
plt.title(TITLE)

# function to show the plot
plt.show()
fig.savefig('graph.png', dpi=fig.dpi)

唯一缺少的一点是减少2个滴答之间的间隔。目前是2小时。
在这方面的任何帮助或指针是高度赞赏。

ma8fv8wu

ma8fv8wu1#

对于只是完全旋转标签一样,在您的excel绘图。试试这个。

plt.setp( ax.xaxis.get_majorticklabels(), rotation=90)
v1l68za4

v1l68za42#

在做了更多的研究之后,我终于能够把它画出来了。

dates = []
for ts in time_stamp:
   local_d = datetime.strptime(ts, '%H:%M')
   dates.append( local_d)

fig, ax = plt.subplots()
plt.setp( ax.xaxis.get_majorticklabels(), rotation=90)
plt.plot(dates, requests)
ax.xaxis.set_major_locator(mdates.MinuteLocator(interval=20))
ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))
plt.xlabel(X_AXIS_NAME)
plt.ylabel(Y_AXIS_NAME)
plt.title(TITLE)
plt.show()
fig.savefig('graph.png', dpi=fig.dpi)

感谢社区!

mgdq6dx1

mgdq6dx13#

问题不在于数据太多,而在于刻度标签的密度。如果数字太窄,autofmt_xdate甚至会在标记了少量刻度的情况下失败。因此解决方案是减少标记刻度的数量。如果只标记完整的小时而不打印分钟,则不需要旋转。请注意,MinuteLocator(interval=60)会失败--以小数小时的偏移量自动放置刻度。

import datetime as dt
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from numpy import arange # for fake x data

y = [3, 30, 3000, 2900, 3100, 1000, 3000, 2000, 200, 20, 2] # roughly
x = arange(len(y))*dt.timedelta(seconds=4800) + dt.datetime.strptime('05:50', '%H:%M')

fig, ax = plt.subplots(figsize=(10,4))
ax.set_title('Request Load (<server> <service> <date>)')
ax.set_xlabel('time of day in hours (timezone)')
ax.set_ylabel('requests per minute')
ax.plot(x, y)
ax.xaxis.set_minor_locator(mdates.MinuteLocator(interval=15))
ax.xaxis.set_major_locator(mdates.HourLocator(interval=1))
ax.xaxis.set_major_formatter(mdates.DateFormatter('%H'))
ax.set_ylim(0)
fig.tight_layout()
fig.show()

3pvhb19x

3pvhb19x4#

实际上,您可以使用matplotlib的autofmt_xdate()方法来解决您所面临的问题。
只需在plt.show()之前添加以下行

plt.gcf().autofmt_xdate()

默认值很好用,所以很可能您可以不带任何参数直接调用它,但是为了完整起见,您可以使用下面指定的参数。
报价matplotlib documentation (v.3.1.1)
autofmt_xdate(self, bottom=0.2, rotation=30, ha='right', which=None)
日期刻度标签通常重叠,因此旋转并右对齐它们是很有用的。此外,一个常见的用例是多个子区共享X轴,其中X轴是日期数据。刻度标签通常很长,这有助于在底部子区旋转它们,并在其他子区关闭它们,以及关闭xlabel。参数:

  • bottom : scalar

最下面的子情节为subplots_adjust()。

  • rotation : angle in degrees

xtick标签的旋转。

  • ha : string

xticklabel的水平对齐方式。

  • which : {None, 'major', 'minor', 'both'}

选择要旋转的刻度标签。默认值为"无",其作用与主刻度相同

相关问题