【问题标题】:matplotlib event.xdata out of timeries rangematplotlib event.xdata 超出时间范围
【发布时间】:2019-01-04 17:38:17
【问题描述】:

在绘制pandas.Timeseries 时使用matplotlib event.xdata 时遇到问题,我试图重现very related question 中提出的答案,但得到了一个非常奇怪的行为。

这是代码,适用于 python3 并在 on_click() 函数中添加了一些内容:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

import matplotlib.dates as mdates

def on_click(event):
    if event.inaxes is not None:
        # provide raw and converted x data
        print(f"{event.xdata} --> {mdates.num2date(event.xdata)}")
    # add a vertical line at clicked location
    line = ax.axvline(x=event.xdata)
    plt.draw()

t = pd.date_range('2015-11-01', '2016-01-06', freq='H')
y = np.random.normal(0, 1, t.size).cumsum()

df = pd.DataFrame({'Y':y}, index=t)

fig, ax = plt.subplots()
line = None
df.plot(ax=ax)
fig.canvas.mpl_connect('button_press_event', on_click)
plt.show()

如果我启动它,我会得到下图,预计日期范围在 2015 年 11 月到 2016 年 1 月之间,窗口页脚中提供的光标位置信息也是如此(此处为 2015-11-01 10:00 ),以及垂直线的正确位置:

但是,命令行输出如下:

C:\Users\me\Documents\code\>python matplotlib_even.xdate_num2date.py
402189.6454115977 --> 1102-02-27 15:29:23.562039+00:00
402907.10400704964 --> 1104-02-15 02:29:46.209088+00:00

那些event.xdata 值显然超出了输入数据范围和 x 轴数据范围,并且无法用于以后使用(例如,尝试在 serie 中找到最接近的 y 值)。

那么,有谁知道我怎样才能得到正确的xdata

【问题讨论】:

标签: python datetime matplotlib


【解决方案1】:

matplotlib/pandas 在您链接的the answer to the related question 和现在之间处理日期时间信息的方式一定有所改变。我无法评论原因,但我找到了解决您问题的方法。

我仔细研究了显示状态栏左下角坐标的代码,发现当您绘制时间序列时,pandas 会修补打印此信息和replaces it with this one 的函数。

从那里,您可以看到您需要将浮点值转换为Period 对象。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt


def on_click(event):
    print(pd.Period(ordinal=int(event.xdata), freq='H'))


t = pd.date_range('2015-11-01', '2016-01-06', freq='H')
y = np.random.normal(0, 1, t.size).cumsum()

df = pd.DataFrame({'Y': y}, index=t)

fig, ax = plt.subplots()
df.plot(ax=ax)
fig.canvas.mpl_connect('button_press_event', on_click)
plt.show()

【讨论】:

  • 哇,感谢您的搜索,它解释了示例的意外行为。给我一些时间来尝试一下我的真实数据,这些数据不是基于 date_range 的,我不确定我是否可以检索到 pd.Period 调用的 freq 参数。
  • 请注意,这在这种情况下效果很好,但在例如df.plot(ax=ax, x_compat=True),需要使用最初尝试的解决方案。为了使原始消息独立于情节类型,也可以使用print(f"{event.xdata} --> {event.inaxes.format_coord(event.xdata,event.ydata)}")
  • 也不错,因为format_coord 确实是replaced by pandas。但是,当我只对 'native' 类型的 x 值感兴趣时,这会将 x 和 y 轴组合在一个 str 对象中。
  • 好的,经过一番搜索,我真正的问题是完全不同的(数据框在某种时间索引上绘制,没有freq);因此这个答案是相关的,我会提出一个新问题。
猜你喜欢
  • 2011-12-22
  • 2016-01-04
  • 1970-01-01
  • 2023-01-27
  • 1970-01-01
  • 2012-05-04
  • 2020-05-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多