Создайте новое окно / поток Tk в сеансе PyMOL и выведите на него граф matplotlib

Я хотел бы построить график с помощью библиотеки matplotlib и вызвать его из PyMOL как отдельное окно Tkinter (Tk). Кажется, что эта задача не простая, так как требует нескольких потоков, а также некоторой настройки мелодии matplotlib / Tk ( https://github.com/speleo3/pymol-psico/blob/master/psico/matplotlib_fix.py), Matplotlib предлагает так называемый интерактивный режим, который я реализовал в упрощенном примере ниже. Этот код хорошо работает в Windows, если я устанавливаю его как плагин. Напротив, он падает на Mac, а также при запуске из cmd с помощью команды "run".

Вопрос: Как создать новое окно / поток Tk в сеансе PyMOL и вывести на него граф 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)

1 ответ

Я нашел решение. Надеюсь, это будет полезно:

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)
Другие вопросы по тегам