matplotlib中多个子图上的MultiCursor不起作用

tcbh2hod  于 2023-02-13  发布在  其他
关注(0)|答案(1)|浏览(189)

我正在开发一个GUI应用程序,其中将有多个动态子图,我希望有一个光标集成,用于“Matplotlib的MultiCursor小工具”代码似乎都很好,没有任何错误,但光标单独未显示在屏幕上。下面是我目前使用的一个小代码片段函数

import numpy as np
import PySimpleGUI as sg
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg,
                                               NavigationToolbar2Tk)
from matplotlib.widgets import Cursor
from matplotlib.widgets import MultiCursor
from matplotlib.gridspec import GridSpec
from matplotlib.figure import Figure

class Toolbar(NavigationToolbar2Tk):

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

def repack(widget, option):
    pack_info = widget.pack_info()
    pack_info.update(option)
    widget.pack(**pack_info)

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_idle()
    toolbar = Toolbar(figure_canvas_agg, canvas_toolbar)
    toolbar.update()
    figure_canvas_agg.get_tk_widget().pack(side='right', fill='both', expand=1)

layout=[
        [
            sg.Frame(
                'Controls',
                expand_x=True,
                layout=[[
                    sg.Canvas(key='controls_cv')
                ]])
        ],
            [
                sg.Canvas(
                    key='fig_cv',
                    size=(1024, 525),  #(W,H)
                    expand_x=True,
                    expand_y=True,
                    background_color='black')
            ],
        ]

window = sg.Window('Data Visualization Tool',
                   layout=layout,
                   location=(0, 0),
                  
                   resizable=True,
                   margins=(0, 0),
                   finalize=True)

fig = Figure()

def get_data_ax(x_data, y_data, y_label, marker_sym=None):
    ax = fig.add_subplot()
    lines = ax.step(
        x_data,
        y_data,
    
        marker=marker_sym,
        where='post')
    
    return ax, lines
cursor_handle_list = []
axes_handle_list = []
def on_move(event, flag=False, c_flag=False):
    global cursor_present_flag, cursor_handle_list, axes_handle_list
    if event.dblclick:     
        def change_cursor_position(handle_obj):
            for handles in handle_obj:
                handles.set_xdata(float(event.xdata))   
        if event.inaxes is not None:
            ax = event.inaxes
            if ax not in axes_handle_list:
                cursor_handle = ax.axvline(event.xdata, color ='red', lw = .75, alpha = 0.65, visible=True)
                cursor_handle_list.append(cursor_handle)
                axes_handle_list.append(ax)
            else:
                change_cursor_position(cursor_handle_list)
            
            draw_figure_w_toolbar(window['fig_cv'].TKCanvas, fig,
                                        window['controls_cv'].TKCanvas)
        window.refresh()

fig.canvas.mpl_connect("button_press_event", on_move)
t = np.arange(0.0, 2.0, 0.01)
s = 1 + np.sin(2 * np.pi * t) 
num_rows = 2
gs = GridSpec(num_rows, 1, hspace=0)
ax0, lines = get_data_ax(t, s, 'test')

ax0.set_subplotspec(gs[0])
fig.add_subplot(ax0)
ax, lines = get_data_ax(t, s, 'test')
ax.set_subplotspec(gs[1])
fig.add_subplot(ax)
ax.get_shared_x_axes().join(ax0, ax)

graph = FigureCanvasTkAgg(fig, master=window['fig_cv'].TKCanvas)
cursor_multi = MultiCursor(graph, [ax,], color='r', lw=2.0, vertOn=True)
graph.draw()  
draw_figure_w_toolbar(window['fig_cv'].TKCanvas, fig,
                                      window['controls_cv'].TKCanvas)
while True:
    event, values = window.read()
    if event in (sg.WIN_CLOSED, 'Exit'):
        break

我尝试将axvline与matplotlib事件一起使用,但结果并不令人满意。我在某个地方看到,将MultiCursor的返回值定义为globl应该可以解决这个问题,但在我的情况下并没有出现这种情况。接下来,我尝试将plt.var_name简单地作为一个变量,用于捕获从MultiCursor返回的对象,但即使这样也没有产生任何结果。**注意:**带有mpl_connect和on_move回调的代码与axvline集成只是我尝试的一个变通方案,因为MultiCursor不工作,如果不需要,您可以丢弃该部分

roejwanj

roejwanj1#

这是因为在为轴对象创建FigureCanvasTkAgg之前,您创建了MultiCursor小部件。

draw_figure_w_toolbar(window['fig_cv'].TKCanvas, ...)
cursor_multi = MultiCursor(None, [ax,], ...)

还请注意,建议将MultiCursor()的第一个参数设置为None,因为它会被忽略。此外,您的代码包含许多问题,例如未使用的对象graph

相关问题