英文:
Incorrect timestamps are shown on the x-axis
问题
以下是翻译好的部分:
我使用以下代码生成了以下柱状图:
import matplotlib as mplt
from matplotlib import dates, pyplot
from matplotlib.transforms import ScaledTranslation
import numpy as np
import pandas as pd
ts = pd.date_range('2023/01/01', '2023/01/06', freq='3H', tz='utc')
xs = np.arange(len(ts))
df = pd.DataFrame({'date':ts,'value':np.ones(shape=len(ts)), 'intensity':np.random.uniform(0, 10, len(ts))})
colors = []
for i in df.intensity:
if 0 <= i < 6:
colors.append('#75FF71')
elif 6 <= i < 8:
colors.append('#FFC53D')
else:
colors.append('#FF5C5C')
# pyplot.box
fig, ax = pyplot.subplots(figsize = (24,1), constrained_layout=False)
ax.yaxis.set_ticklabels(labels=[])
ax.yaxis.set_visible(False)
ax.grid(False)
ax.set_frame_on(False)
hour_locs = dates.HourLocator(byhour=[6, 12, 18])
hour_locs_fmt = dates.DateFormatter('%H:%M')
ax.xaxis.set_minor_locator(hour_locs)
ax.xaxis.set_minor_formatter(hour_locs_fmt)
day_locs = dates.DayLocator(interval=1)
day_locs_fmt = dates.DateFormatter('%B %-d')
ax.xaxis.set_major_locator(day_locs)
ax.xaxis.set_major_formatter(day_locs_fmt)
ax.xaxis.set_tick_params(which='major', pad=-10, length=40)
ax.bar(df.date, df.value, color=colors)
offset = ScaledTranslation(1.6, 0, fig.dpi_scale_trans)
for label in ax.xaxis.get_majorticklabels():
label.set_transform(label.get_transform() + offset)
时间戳从2023/01/01 00:00:00+000(UTC)开始,但图表显示数据从前一天的大约15:00开始。我猜想matplotlib忽略了数据中的时区信息。
我尝试在定位器和格式化器中指定TZ,但没有成功。
如何让matplotlib绘制UTC时间?
英文:
I have the following bar plot being generated with the following code:
import matplotlib as mplt
from matplotlib import dates, pyplot
from matplotlib.transforms import ScaledTranslation
import numpy as np
import pandas as pd
ts = pd.date_range('2023/01/01', '2023/01/06', freq='3H', tz='utc')
xs = np.arange(len(ts))
df = pd.DataFrame({'date':ts,'value':np.ones(shape=len(ts)), 'intensity':np.random.uniform(0, 10, len(ts))})
colors = []
for i in df.intensity:
if 0 <= i < 6:
colors.append('#75FF71')
elif 6 <= i < 8:
colors.append('#FFC53D')
else:
colors.append('#FF5C5C')
# pyplot.box
fig, ax = pyplot.subplots(figsize = (24,1), constrained_layout=False)
ax.yaxis.set_ticklabels(labels=[])
ax.yaxis.set_visible(False)
ax.grid(False)
ax.set_frame_on(False)
hour_locs = dates.HourLocator(byhour=[6, 12, 18])
hour_locs_fmt = dates.DateFormatter('%H:%M')
ax.xaxis.set_minor_locator(hour_locs)
ax.xaxis.set_minor_formatter(hour_locs_fmt)
day_locs = dates.DayLocator(interval=1)
day_locs_fmt = dates.DateFormatter('%B %-d')
ax.xaxis.set_major_locator(day_locs)
ax.xaxis.set_major_formatter(day_locs_fmt)
ax.xaxis.set_tick_params(which='major', pad=-10, length=40)
ax.bar(df.date, df.value, color=colors)
offset = ScaledTranslation(1.6, 0, fig.dpi_scale_trans)
for label in ax.xaxis.get_majorticklabels():
label.set_transform(label.get_transform() + offset)
The timestamps start from 2023/01/01 00:00:00+000 (UTC), however the plot shows that the data is starting at ~15:00 the day before. I'm assuming that matplotlib is ignoring the timezone in the data.
I did try specifying TZ in the locators and formatter in vain.
How do I get matplotlib to plot in UTC?
答案1
得分: 1
由于您正在绘制柱状图,它会在两端添加一些额外的空间。这就是您看到额外空间的原因。最后,在末尾添加这行代码 (ax.set_xlim(...)
),强制图形从您想要的时间开始和结束。
ax.set_xlim(df.date.min(), df.date.max())
您将获得下面的图表... 希望这是您要找的...
编辑:
我意识到最后的日期(1月6日)也显示出来了。如果您不希望看到它,您可以将 date.max()
替换为 df.date.nlargest(2).iloc[-1]
,这将提供前一个值而不显示最后的日期。但是,它还将删除最后的垂直线和任何时间(如果可用)... 您可以选择哪一个您更喜欢... 下面是另一个图表。
编辑 #2:
要删除最后的标签(6月6日)并保留最后的主刻度线,您可以使用第一种选项,即先显示6月6日,然后删除最后一个刻度标签。请注意,这对于您的情况非常特殊,因为您的最后一天的数据是一天中的00小时,并且如果您更改数据,可能无法正常工作...
## 在 pyplot.show() 之前添加的代码 ##
ax.set_xlim(df.date.min(), df.date.max())
x_ticks = ax.xaxis.get_major_ticks() ## 获取所有刻度
x_ticks[-1].label1.set_visible(False) ## 删除最后一个刻度标签
英文:
As you are plotting bars, it adds a little extra space on either ends. This is the reason you are seeing the extra space. At the end, add this line (ax.set_xlim(...)
), forcing the plot to start and end at the times you want.
ax.set_xlim(df.date.min(), df.date.max())
You will get the below plot... hope this is what you are looking for...
EDIT:
I realize that the last date (Jan 6th) is also showing up. In case you don't want that, you can replace the date.max() by df.date.nlargest(2).iloc[-1]
, which will give the previous value and not show the last date. However, it will also remove the last vertical line and any time if it is available... your call on which one you would prefer... below is the other plot.
EDIT #2:
To remove the last label (June 6) AND keep the last major tick line, you can use the first option of having June 6th and then remove the last ticklabel. Note that this is very specific to your case where you have the last data as 00 hours of a day and may not work if you change the data...
## Code to add before pyplot.show() ##
ax.set_xlim(df.date.min(), df.date.max())
x_ticks = ax.xaxis.get_major_ticks() ## Get all ticks
x_ticks[-1].label1.set_visible(False) ## Remove last tick label
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论