如何检测事件并调用用户定义的函数来编辑 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)
我正在绘制巨大的数据集(长度超过 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)