如何向 matplotlib 中的现有绘图添加垂直线

问题描述 投票:0回答:1

我有一个大型数据集(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")

这个最少的代码产生:
Vin_time

如何使用 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()

Cursor

这并不令人满意,因为不会永久显示光标(缩放会杀死它)。此外,没有在绘图上动态添加符号的选项。

添加了部分点击事件。这会将一些当前鼠标位置信息带到控制台。如何转移到剧情中?

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()
python matplotlib
1个回答
0
投票

工作脚本,以“十字”形状显示光标(以帮助提高精度)。
还在绘图上显示结果。

Cursor and info in plot area

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 收集鼠标点击位置并通过位置绘制垂直线

只需执行上面的方法,解决方案就准备好了。

© www.soinside.com 2019 - 2024. All rights reserved.