Создание окна интерактивного черчения matplotlib для существующей фигуры - PullRequest
3 голосов
/ 01 сентября 2011

Я пишу программу, которая подгоняет кривые к большим наборам координатных данных xy.Часто полезно наблюдать за ходом алгоритма, составляя график и отображая каждую итерацию в процессе подгонки.Я использую matplotlib для построения графиков.

Я хотел бы создать фигуру в главном потоке, а затем передать ее в дочерний поток, который ее отображает.Таким образом, у меня есть доступ ко всем методам и атрибутам фигуры в основном потоке.Я могу построить график, вызвав fig.gca (). Plot (), и нарисовать, вызвав fig.canvas.draw ().

Я не могу понять, как создать интерактивное графическое окно, которое показывает только рисунок, который я передаю ему.Прямо сейчас я использую matplotlib.pyplot.show (), которая отображает мою фигуру, но также отображает любые другие фигуры, которые могли быть определены в программе.Есть ли объектно-ориентированный способ создания интерактивного окна для конкретной фигуры?Я ищу решение, которое не опирается на неподдерживаемые интерфейсы в Matplotlib.

Вот пост, который похож, но он все еще не отвечает на мой вопрос: Интерактивная фигура с OO Matplotlib

Я никогда не понимал, почему matplotlib всегда кажетсяиспользовать текущие объекты (текущий рисунок, текущие оси и т. д.), а не конкретные объекты (например, почему бы не использовать matplotlib.pyplot.show (рис.), а не просто show ()?). Я думаю, что я что-то упустил.Если бы кто-то мог пролить свет на то, почему Matplotlib разработан таким образом, или как я неправильно понимаю и / или неправильно его использую, это также будет оценено.

Вот мой код:

import matplotlib.pyplot
import threading
import time

class Plotter():
    def __init__(self,fig):
        t = threading.Thread(target=self.PlottingThread,args=(fig,))
        t.start()       

    def PlottingThread(self,fig):
        #This line shows fig1 AND fig2 from below. I want it to show fig ONLY.
        matplotlib.pyplot.show()  

if __name__ == "__main__":
    fig1 = matplotlib.pyplot.figure()
    fig2 = matplotlib.pyplot.figure()

    Plotter(fig1)

    fig1.gca().clear()
    fig1.gca().plot([1,2,3])
    fig1.canvas.draw()

1 Ответ

2 голосов
/ 02 сентября 2011

Мне кажется, я понял:

import Tkinter
import threading
import matplotlib.backends.backend_tkagg

root = Tkinter.Tk()

class Plotter():
    def __init__(self,fig):
        t = threading.Thread(target=self.PlottingThread,args=(fig,))
        t.start()       

    def PlottingThread(self,fig):        
        canvas = matplotlib.backends.backend_tkagg.FigureCanvasTkAgg(fig, master=root)
        canvas.show()
        canvas.get_tk_widget().pack(side=Tkinter.TOP, fill=Tkinter.BOTH, expand=1)

        toolbar = matplotlib.backends.backend_tkagg.NavigationToolbar2TkAgg(canvas, root)
        toolbar.update()
        canvas._tkcanvas.pack(side=Tkinter.TOP, fill=Tkinter.BOTH, expand=1)

        Tkinter.mainloop()

if __name__ == "__main__":
    import time

    fig1 = matplotlib.figure.Figure(figsize=(5,4), dpi=100)
    fig1.gca().plot([1,2,3])     
    fig2 = matplotlib.figure.Figure(figsize=(5,4), dpi=100)
    fig2.gca().plot([3,2,1])

    #Shows fig1 and not fig2, just like it's supposed to
    Plotter(fig1)

    time.sleep(1)

    #I can still plot to fig1 from my main thread
    fig1.gca().clear()
    fig1.gca().plot([5,2,7])
    fig1.canvas.draw()

Единственное, что если вы попытаетесь создать два экземпляра Plotter, все это рухнет. Это не слишком важно для моего приложения, но, вероятно, это означает, что я неправильно использую Tkinter. Предложения / исправления приветствуются.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...