首页 > 解决方案 > 嵌入在 PySimpleGUI 窗口选项卡中的缩放 +/- 功能 matplotlib 窗口

问题描述

我有以下代码(基于使用滚轮缩放的 Matplotlib 绘图)。我试图将它嵌入到 PySimpleGUI 窗口选项卡中,到目前为止我还不能这样做。

我设法使它与 Tkinter 窗口一起工作,但我的主要 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()

标签: pythonmatplotlibpysimplegui

解决方案


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

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 的窗口布局上使用fig= plt.figure()window['canvas']=sg.Canvas(key='canvas'),然后按如下方式应用 ZoomPan 类:

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

推荐阅读