如何检测事件并调用用户定义的函数来编辑 Python matplotlib 上的刻度标签?

How to detect an event and call user defined function to edit tick labels on Python matplotlib?

我正在绘制巨大的数据集(长度超过 5E5 的数组),其中 x 值是 utc 时间戳。我想将它们转换为格式 HH:MM:SS 而不是例如1.47332886e+09 秒。因此我做了一个小函数来转换时间戳。由于我正在绘制的数据集很大,我无法将所有时间戳转换为日期时间元组。这会花太长时间。所以我想我可以读取 xtick 值并仅将这些值转换为所需的格式。问题是,当我这样做时,x-tick 标签是固定的,并且通过缩放 x-tick 标签,它们保持不变。所以基本上每次缩放时我都需要 运行 我的函数。我宁愿自动化这个。所以我尝试为此使用事件处理,但找不到在事件处理程序中调用我的函数的方法。

如何正确调用事件处理程序中的函数?或者有更好的方法来实现我的目标吗?

(我正在使用 Python 3.3)

这是我的代码:

def timeStamp2dateTime(timeArray):
    import datetime
    import numpy as np
    # first loop definition:
    timeArrayExport = []
    timeArrayExport = datetime.datetime.fromtimestamp(timeArray[0])
    for i in range(1,len(timeArray)):
        # Convert timestamps to datetime
        timeArrayExport = np.append( timeArrayExport, datetime.datetime.fromtimestamp(timeArray[i]) )
    return(timeArrayExport)


def set_xticklabels_timestamp2time(ax):
    '''
    this function reads xtick values (assuming that they are timestamps) and
    converts the xtick values to datetime format. from datetime format is
    xticklabel list generated in format HH:MM:SS and also added to the plot
    which has the handle "ax" (function input).
    '''
    import matplotlib.pyplot as plt
    # manipulating the x-ticks -----
    plt.pause(0.1) # update the plot
    xticks = ax.get_xticks()
    xticks_dt = timeStamp2dateTime(xticks)
    xlabels = []
    for item in xticks_dt:
        xlabels.append(str(item.hour).zfill(2) +':'+ str(item.minute).zfill(2) +':'+ str(item.second).zfill(2))
    ax.set_xticklabels(xlabels)
    plt.gcf().autofmt_xdate() # rotates the x-axis values so that it is more clear to read
    plt.pause(0.001) # update the plot
    return(ax)


def onrelease(event):
    ax = set_xticklabels_timestamp2time(ax)


import numpy as np
import matplotlib.pyplot as plt

# example data
x = np.arange(1.47332886e+09,1.47333886e+09) # UTC timestamps
y = np.sin(np.arange(len(x))/1000) + np.cos(np.arange(len(x))/100)

fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(x,y,'.-')
ax.grid(True)

ax = set_xticklabels_timestamp2time(ax)

# try to automate the xtick label convertion
try:
    cid = fig.canvas.mpl_connect('button_release_event', set_xticklabels_timestamp2time(ax))
except:
    cid = fig.canvas.mpl_connect('button_release_event', onrelease)
# => both ways fails

感谢您阅读本文!

您正在寻找的是一个 ticklabelformatter。参见 the documentation or this example。它所做的是让 matplotlib 弄清楚刻度应该是什么,并且每次它们改变时,放置正确的标签。在链接示例中,他们使用 matplotlib.ticker.FuncFormatter,它采用用户定义的函数

def millions(x, pos):
    'The two args are the value (x) and tick position (pos)'
    return '$%1.1fM' % (x*1e-6)

简单地将输入值 x 缩放到数百万,并将其附加到字符串 x_in_millions M,returned 作为新的刻度标签。如果您创建以秒为单位获取时间戳并将其转换为您喜欢的格式和 return 字符串的函数,这也应该适用于您的情况。定义函数后,您可以使用以下命令对其进行设置:

from matplotlib.ticker import FuncFormatter
formatter = FuncFormatter(millions)
ax.yaxis.set_major_formatter(formatter)