缩放 +/- matplotlib window 嵌入在 PySimpleGUI window 选项卡中

Zoom +/- capable matplotlib window embedded in a PySimpleGUI window tab

我有以下代码(基于Matplotlib plot zooming with scroll wheel)。我试图将它嵌入到 PySimpleGUI window 选项卡中,但到目前为止我还没有成功。

我设法让它与 Tkinter 一起工作 window,但我的主要 GUI 主要是 PySImpleGUI。

from matplotlib.pyplot import figure, show 
import numpy import PySimpleGUI as sg 
import matplotlib.pyplot as plt

class ZoomPan:
    def __init__(self):
        self.press = None
        self.cur_xlim = None
        self.cur_ylim = None
        self.x0 = None
        self.y0 = None
        self.x1 = None
        self.y1 = None
        self.xpress = None
        self.ypress = None

    def zoom_factory(self, ax, base_scale = 2.):
        def zoom(event):
            cur_xlim = ax.get_xlim()
            cur_ylim = ax.get_ylim()

            xdata = event.xdata # get event x location
            ydata = event.ydata # get event y location

            if event.button == 'up':
                # deal with zoom in
                scale_factor = 1 / base_scale
            elif event.button == 'down':
                # deal with zoom out
                scale_factor = base_scale
            else:
                # deal with something that should never happen
                scale_factor = 1
                print (event.button)

            new_width = (cur_xlim[1] - cur_xlim[0]) * scale_factor
            new_height = (cur_ylim[1] - cur_ylim[0]) * scale_factor

            relx = (cur_xlim[1] - xdata)/(cur_xlim[1] - cur_xlim[0])
            rely = (cur_ylim[1] - ydata)/(cur_ylim[1] - cur_ylim[0])

            ax.set_xlim([xdata - new_width * (1-relx), xdata + new_width * (relx)])
            ax.set_ylim([ydata - new_height * (1-rely), ydata + new_height * (rely)])
            ax.figure.canvas.draw()

        fig = ax.get_figure() # get the figure of interest
        fig.canvas.mpl_connect('scroll_event', zoom)

        return zoom

    def pan_factory(self, ax):
        def onPress(event):
            if event.inaxes != ax: return
            self.cur_xlim = ax.get_xlim()
            self.cur_ylim = ax.get_ylim()
            self.press = self.x0, self.y0, event.xdata, event.ydata
            self.x0, self.y0, self.xpress, self.ypress = self.press

        def onRelease(event):
            self.press = None
            ax.figure.canvas.draw()

        def onMotion(event):
            if self.press is None: return
            if event.inaxes != ax: return
            dx = event.xdata - self.xpress
            dy = event.ydata - self.ypress
            self.cur_xlim -= dx
            self.cur_ylim -= dy
            ax.set_xlim(self.cur_xlim)
            ax.set_ylim(self.cur_ylim)

            ax.figure.canvas.draw()

        fig = ax.get_figure() # get the figure of interest

        # attach the call back
        fig.canvas.mpl_connect('button_press_event',onPress)
        fig.canvas.mpl_connect('button_release_event',onRelease)
        fig.canvas.mpl_connect('motion_notify_event',onMotion)

        #return the function
        return onMotion

"FIGURE"
plt.figure(1) 
fig = plt.gcf()   
ax = fig.add_subplot(111) 
ax.clear()
ax.set_title('') 

"RANDOM PLOT"
x,y,s,c = numpy.random.rand(4,200) s *= 200   
ax.scatter(x,y,s,c, label='label')

"FIGURE CONSTANT"
ax.grid() 
ax.set_xlabel('COORDENADA ESTE', size=15) 
ax.set_ylabel('COORDENADA NORTE', size=15) 
plt.tight_layout(pad=0.05, h_pad=0.05, w_pad=0.05, rect=(0.05,-0.05,0.95,0.95)) 
ax.legend(loc=2, bbox_to_anchor=(-0.15, 1)) 
mng = plt.get_current_fig_manager() 
mng.window.showMaximized()

"PLOT"
zp = ZoomPan() 
figZoom = zp.zoom_factory(ax, base_scale = 1.1) 
figPan= zp.pan_factory(ax) 
show()

你像往常一样开始你的情节,然后你必须为 pysimplegui window canvas 创建实际的无花果,如下所示:

def draw_figure(canvas, figure, loc=(0, 0)):
    figure_canvas_agg = FigureCanvasTkAgg(figure, canvas)
    figure_canvas_agg.draw()
    figure_canvas_agg.get_tk_widget().pack(side='top', fill='both', expand=1)
    return figure_canvas_agg

如:

fig_canvas_agg = draw_figure(window['canvas'].TKCanvas, fig)

在 PYSImpleGUI 的 window 布局上使用 fig= plt.figure()window['canvas']=sg.Canvas(key='canvas'),然后按如下方式应用 ZoomPan class:

zp = plot_func()
figZoom = zp.zoom_factory(ax1, base_scale=1.7)
figPan = zp.pan_factory(ax1)