首页 > 解决方案 > 如何在matplotlib中右键单击平移?

问题描述

我正在编写一个小程序来可视化我的数据并与之交互。如果重要,GUI 位于Tkintervia中PySimpleGUI

为了在不同的软件包之间保持相同的鼠标手势,我希望能够通过matplotlib.pyplot右键单击和拖动来平移我正在绘制的数据。

我目前关于如何做到这一点的搜索没有取得任何成果。

我怎样才能做到这一点?

标签: pythonmatplotlib

解决方案


不确定这是否是您的要求,没有更多解释。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
from matplotlib.widgets import SpanSelector
import PySimpleGUI as sg


def draw_figure_w_toolbar(canvas, fig, canvas_toolbar):
    if canvas.children:
        for child in canvas.winfo_children():
            child.destroy()
    if canvas_toolbar.children:
        for child in canvas_toolbar.winfo_children():
            child.destroy()
    figure_canvas_agg = FigureCanvasTkAgg(fig, master=canvas)
    figure_canvas_agg.draw()
    toolbar = Toolbar(figure_canvas_agg, canvas_toolbar)
    toolbar.update()
    figure_canvas_agg.get_tk_widget().pack(side='right', fill='both', expand=1)

def onselect(xmin, xmax):
    indmin, indmax = np.searchsorted(x, (xmin, xmax))
    indmax = min(len(x) - 1, indmax)
    thisx = x[indmin:indmax]
    thisy = y[indmin:indmax]
    line2.set_data(thisx, thisy)
    ax2.set_xlim(thisx[0], thisx[-1])
    ax2.set_ylim(thisy.min(), thisy.max())
    fig.canvas.draw()

#def onmove(xmin, xmax):
#    window.refresh()

class Toolbar(NavigationToolbar2Tk):
    def __init__(self, *args, **kwargs):
        super(Toolbar, self).__init__(*args, **kwargs)


# ------------------------------- PySimpleGUI CODE

layout = [
    [sg.T('Graph: y=sin(x)')],
    [sg.B('Plot'), sg.B('Exit')],
    [sg.T('Controls:')],
    [sg.Canvas(key='controls_cv')],
    [sg.T('Figure:')],
    [sg.Column(
        layout=[
            [sg.Canvas(key='fig_cv',
                       # it's important that you set this size
                       size=(400 * 2, 400)
                       )]
        ],
        background_color='#DAE0E6',
        pad=(0, 0)
    )],
    [sg.B('Alive?')]

]

window = sg.Window('Graph with controls', layout)

while True:
    event, values = window.read()
    print(event, values)
    if event in (sg.WIN_CLOSED, 'Exit'):  # always,  always give a way out!
        break
    elif event == 'Plot':
        # Fixing random state for reproducibility
        np.random.seed(19680801)

        fig, (ax1, ax2) = plt.subplots(2, figsize=(8, 6))
        ax1.set(facecolor='#FFFFCC')

        x = np.arange(0.0, 5.0, 0.01)
        y = np.sin(2*np.pi*x) + 0.5*np.random.randn(len(x))

        ax1.plot(x, y, '-')
        ax1.set_ylim(-2, 2)
        ax1.set_title('Press mouse button and drag to test')

        ax2.set(facecolor='#FFFFCC')
        line2, = ax2.plot(x, y, '-')

        span = SpanSelector(ax1, onselect, 'horizontal', useblit=True,
            rectprops=dict(alpha=0.5, facecolor='red'), #onmove_callback=onmove,
            span_stays=True)

        # ------------------------------- Instead of plt.show()
        draw_figure_w_toolbar(window['fig_cv'].TKCanvas, fig, window['controls_cv'].TKCanvas)

window.close()

推荐阅读