我有一个大型数据集(5M 点)需要可视化。有数据点和时间轴。
及时发生一些事件,价值观会发生显着变化。
我想以垂直线的形式添加两个“可点击”元素来标记两个提到的事件,稍后我想显示它们的时间值和计算出的差异。
import matplotlib.pyplot as plt
time = [1,2,3,4,5,6,7,8,9,10,11,12,13,13,15,16,17,18,19,20]
ch1_scope = [0,0,0,0,5,5,5,5,0,0,0,0,5,5,5,5,0,0,0,0]
ch2_scope = [5,5,5,5,0,0,0,0,5,5,5,5,0,0,0,0,5,5,5,5]
fig, (ax1, ax2) = plt.subplots(2, sharex = True)
ax1.plot(time, ch1_scope, 'tab:red')
ax1.set_title("Vph1")
ax2.plot(time, ch2_scope, 'tab:olive')
ax2.set_title("Vph2")
如何使用 matplotlib 实现它?是否可以不重新绘图/重新绘制?
一个简单的脚本,可以添加垂直线,这将是一个好的开始。
经过一番尝试,我添加了这个光标:
import matplotlib.pyplot as plt
from matplotlib.widgets import Cursor
time = [1,2,3,4,5,6,7,8,9,10,11,12,13,13,15,16,17,18,19,20]
ch1_scope = [0,0,0,0,5,5,5,5,0,0,0,0,5,5,5,5,0,0,0,0]
ch2_scope = [5,5,5,5,0,0,0,0,5,5,5,5,0,0,0,0,5,5,5,5]
fig, (ax1, ax2) = plt.subplots(2, sharex = True)
ax1.plot(time, ch1_scope, 'tab:red')
ax1.set_title("Vph1")
ax2.plot(time, ch2_scope, 'tab:olive')
ax2.set_title("Vph2")
cursor = Cursor(
ax1, useblit=True, horizOn=False, vertOn=True, color="red", linewidth=0.5)
plt.show()
这并不令人满意,因为不会永久显示光标(缩放会杀死它)。此外,没有在绘图上动态添加符号的选项。
添加了部分点击事件。这会将一些当前鼠标位置信息带到控制台。如何转移到剧情中?
enter code here
import matplotlib.pyplot as plt
from matplotlib.widgets import Cursor
from matplotlib.backend_bases import MouseButton
time = [1,2,3,4,5,6,7,8,9,10,11,12,13,13,15,16,17,18,19,20]
ch1_scope = [0,0,0,0,5,5,5,5,0,0,0,0,5,5,5,5,0,0,0,0]
ch2_scope = [5,5,5,5,0,0,0,0,5,5,5,5,0,0,0,0,5,5,5,5]
fig, (ax1, ax2) = plt.subplots(2, sharex = True)
ax1.plot(time, ch1_scope, 'tab:red')
ax1.set_title("Vph1")
ax2.plot(time, ch2_scope, 'tab:olive')
ax2.set_title("Vph2")
cursor = Cursor(
ax1, useblit=True, horizOn=False, vertOn=True, color="red", linewidth=0.5
)
def on_move(event):
if event.inaxes:
print(f'data coords {event.xdata} {event.ydata},',
f'pixel coords {event.x} {event.y}')
def on_right_click(event):
if event.button is MouseButton.LEFT:
print(f'Clicked LMB: data coords {event.xdata} {event.ydata}')
if event.button is MouseButton.RIGHT:
print('disconnecting callback')
plt.disconnect(binding_id)
binding_id = plt.connect('motion_notify_event', on_move)
plt.connect('button_press_event', on_right_click)
plt.show()
工作脚本,以“十字”形状显示光标(以帮助提高精度)。
还在绘图上显示结果。
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.backend_bases import MouseEvent, MouseButton
class Cursor:
"""
A cross hair cursor.
"""
def __init__(self, ax):
self.ax = ax
#self.mytext = ''
self.horizontal_line = ax.axhline(color='k', lw=0.8, ls='--')
self.vertical_line = ax.axvline(color='k', lw=0.8, ls='--')
# text location in axes coordinates
self.text = ax.text(0.50, 0.9, '', transform=ax.transAxes) # text in plot area coordinates
self.text_calculations = ax.text(0.1, 0.1, 'Calc: ', transform=ax.transAxes)
self.click_x_value = []
def set_cross_hair_visible(self, visible):
need_redraw = self.horizontal_line.get_visible() != visible
self.horizontal_line.set_visible(visible)
self.vertical_line.set_visible(visible)
self.text.set_visible(visible)
return need_redraw
def on_click(self, event):
if event.button is MouseButton.LEFT:
self.click_x_value.append(f'{event.xdata:1.3f}')
if len(self.click_x_value) == 2:
diff = float(self.click_x_value[1]) - float(self.click_x_value[0])
recip = 1/diff
self.text_calculations.set_text('x0: ' + str(self.click_x_value[0]) + ', x1: ' + str(self.click_x_value[1]) +'\n'
+'Difference: ' + str(diff) + '\n' + 'Reciprocal: ' + str(recip))
self.click_x_value = []
self.ax.figure.canvas.draw()
def on_mouse_move(self, event):
if not event.inaxes:
need_redraw = self.set_cross_hair_visible(False)
if need_redraw:
self.ax.figure.canvas.draw()
else:
self.set_cross_hair_visible(True)
x, y = event.xdata, event.ydata
# update the line positions
self.horizontal_line.set_ydata([y])
self.vertical_line.set_xdata([x])
self.text.set_text(f'x={x:1.2f}, y={y:1.2f}') # text appears in plot area
self.ax.figure.canvas.draw()
time = [1,2,3,4,5,6,7,8,9,10,11,12,13,13,15,16,17,18,19,20]
ch1_scope = [0,0,0,0,5,5,5,5,0,0,0,0,5,5,5,5,0,0,0,0]
ch2_scope = [5,5,5,5,0,0,0,0,5,5,5,5,0,0,0,0,5,5,5,5]
fig, ax = plt.subplots()
ax.set_title('Simple cursor')
ax.plot(time, ch1_scope)
cursor = Cursor(ax)
fig.canvas.mpl_connect('motion_notify_event', cursor.on_mouse_move)
fig.canvas.mpl_connect('button_press_event', cursor.on_click)
在图中添加线条(通过鼠标单击)有一个答案:
使用 matplotlib ginput 收集鼠标点击位置并通过位置绘制垂直线
只需执行上面的方法,解决方案就准备好了。