Python 在PyMOL会话中创建一个新的Tk窗口/线程,并在其上输出matplotlib图

Python 在PyMOL会话中创建一个新的Tk窗口/线程,并在其上输出matplotlib图,python,matplotlib,tkinter,pymol,Python,Matplotlib,Tkinter,Pymol,我想通过matplotlib库绘制一个图形,并将其从PyMOL调用为一个独立的Tkinter(Tk)窗口。这项任务似乎并不简单,因为它需要几个线程以及matplotlib/Tk()的一些调优调整。Matplotlib提供了一种所谓的交互模式,我在下面的简化示例中实现了这种模式。如果我将其作为插件安装,则此代码在Windows上运行良好。相比之下,它在Mac上崩溃,当我使用命令“run”从cmd运行它时也会崩溃 问题:如何在PyMOL会话中创建新的Tk窗口/线程并在其上输出matplotlib图

我想通过matplotlib库绘制一个图形,并将其从PyMOL调用为一个独立的Tkinter(Tk)窗口。这项任务似乎并不简单,因为它需要几个线程以及matplotlib/Tk()的一些调优调整。Matplotlib提供了一种所谓的交互模式,我在下面的简化示例中实现了这种模式。如果我将其作为插件安装,则此代码在Windows上运行良好。相比之下,它在Mac上崩溃,当我使用命令“run”从cmd运行它时也会崩溃

问题:如何在PyMOL会话中创建新的Tk窗口/线程并在其上输出matplotlib图

from pymol import cmd, stored
from Tkinter import *
import numpy
import matplotlib
matplotlib.use('TkAgg')

class Plotter:
    def plotDistances(self, x, y):
        plt.figure()
        plt.plot(x, y, 'o')
        plt.tight_layout()
        plt.ion()
        plt.show()

graph1 = Plotter()
xtest = numpy.linspace(1, 300, 300)
ytest = numpy.linspace(1, 300, 300)
graph1.plotDistances(xtest,ytest)

我找到了解决办法。希望这会有所帮助:

import pymol
import matplotlib
matplotlib.use('TkAgg')
from matplotlib.backends import backend_tkagg

def _new_figure_manager(num, *args, **kwargs):
    # import pymol
    if pymol._ext_gui is None:
        return new_figure_manager(num, *args, **kwargs)
    backend_tkagg.show._needmain = False
    import Tkinter as Tk
    from matplotlib.figure import Figure
    from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, FigureManagerTkAgg
    FigureClass = kwargs.pop('FigureClass', Figure)
    print kwargs
    figure = FigureClass(*args, **kwargs)
    window = Tk.Toplevel(master=pymol._ext_gui.root)
    canvas = FigureCanvasTkAgg(figure, master=window)
    figManager = FigureManagerTkAgg(canvas, num, window)
    if matplotlib.is_interactive():
        figManager.show()
    return figManager

new_figure_manager = backend_tkagg.new_figure_manager
backend_tkagg.new_figure_manager = _new_figure_manager

matplotlib.interactive(True)
from matplotlib.figure import Figure
from matplotlib.pyplot import *

import numpy
x = numpy.linspace(1, 300, 300)
y = numpy.linspace(1, 300, 300)

fig1 = figure()
plot = fig1.add_subplot(111)
plot.scatter(x, y)

fig2 = figure()
plot = fig2.add_subplot(111)
plot.scatter(x, 2*y)