Создайте новое окно / поток 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)