[PYTHON] Ich möchte Matplotlib in PySimpleGUI einbetten

Einführung

Wie der Name schon sagt, macht es PySimpleGUI sehr einfach, eine GUI zu erstellen, und Sie können auch eine überraschend leistungsstarke GUI erstellen. Ich verwende PySimpleGUI hauptsächlich, um Werkzeuge für die Forschung zu erstellen, aber ich möchte häufig Matplotlib-Diagramme in die GUI einbetten. Dieser Artikel fasst zusammen, wie es geht. Der Inhalt dieses Artikels basiert auf dem offiziellen Kochbuch und Git Hub.

Was in diesem Artikel zu machen

image.png

Jedes Mal, wenn Sie auf die Schaltfläche Hinzufügen klicken, wird eine zufällige Sinuswelle gezeichnet. Dies ist ein einfaches Programm, mit dem Sie die Leinwand mit der Schaltfläche Löschen löschen können.

Installation

Ich benutze Python 3.8.2. Wenn es sich um ein 3-System handelt, funktioniert es problemlos.

Das offizielle Dokument beschreibt die Installation mit pip, aber Sie können es problemlos mit Anaconda installieren. Ich benutze Anaconda.

pip install pysimplegui
or
conda install pysimplegui

Wenn Sie nicht mit conda installieren können

conda install -c conda-forge pysimplegui

Bitte versuche.

Ich möchte auch Matplotlib verwenden, also installieren Sie es.

conda install matplotlib

Programm

embedded-matplotlib.py


import numpy as np
import PySimpleGUI as sg
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg

#Funktionen, die verhindern, dass die Benutzeroberfläche unscharf wird
def make_dpi_aware():
  import ctypes
  import platform
  if int(platform.release()) >= 8:
    ctypes.windll.shcore.SetProcessDpiAwareness(True)
make_dpi_aware()

#Funktion zum Zeichnen
def draw_figure(canvas, figure):
    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

#Layouterstellung
layout = [[sg.Text('Embed Matplotlib Plot')],
          [sg.Canvas(key='-CANVAS-')],
          [sg.Button("Add"), sg.Button("Clear")]]

#Erstellen Sie ein Fenster. finalisieren=Muss wahr sein.
window = sg.Window('Demo Application - Embedding Matplotlib In PySimpleGUI', layout, finalize=True, element_justification='center', font='Monospace 18')

#Erstellen Sie eine Feige zum Einbetten.
fig = plt.figure(figsize=(5, 4))
ax = fig.add_subplot(111)
ax.set_ylim(-10, 10)

#Assoziiere Feige mit Leinwand.
fig_agg = draw_figure(window['-CANVAS-'].TKCanvas, fig)

#Ereignisschleife
while True:
    event, values = window.read()
    print(event, values)
    # sg.Print(event, values)
    
    if event in (None, "Cancel"):
        break
    
    elif event == "Add":
        #Erstellen geeigneter Plotdaten
        t = np.linspace(0, 7, 100)
        afreq = np.random.randint(1, 10)
        amp = np.random.randint(1, 10)
        y = amp * np.sin(afreq * t)
        
        #Handlung
        ax.plot(t, y, alpha=0.4)
        
        #Nach Änderungen, Abb_agg.draw()Reflektieren Sie die Änderung mit.
        fig_agg.draw()

    elif event == "Clear":
        ax.cla()
        fig_agg.draw()

#schließe das Fenster.
window.close()

Kommentar

Den grundlegenden Teil von PySimpleGUI finden Sie in der offiziellen Dokumentation.

Problem mit der rauen Fensterauflösung

Obwohl es nichts mit dem Hauptmotiv zu tun hat, kann die Auflösung bei der Anzeige eines Fensters mit PySimpleGUI rau und schwer zu erkennen sein. Die Lösung besteht darin, die Funktion make_dpi_aware zu Beginn des Programms auszuführen. Je nach Umgebung scheint es ohne dies ohne Probleme angezeigt zu werden. Ich schreibe diesen Prozess immer zu Beginn meines PySimple-GUI-Programms. Weitere Informationen finden Sie unter Dieses GitHub-Problem.

def make_dpi_aware():
  import ctypes
  import platform
  if int(platform.release()) >= 8:
    ctypes.windll.shcore.SetProcessDpiAwareness(True)

Matplotlib-Plot einbetten

Dies ist das Hauptthema.

Erstellen Sie zunächst ein Fenster. Das Wichtigste dabei ist, Canvas als Element zum Einbetten des Diagramms zu verwenden und beim Erstellen des Fensters "finalize = True" anzugeben.

#Layouterstellung
layout = [[sg.Text('Embed Matplotlib Plot')],
          [sg.Canvas(key='-CANVAS-')],
          [sg.Button("Add"), sg.Button("Clear")]]

#Erstellen Sie ein Fenster. finalisieren=Muss wahr sein.
window = sg.Window('Demo Application - Embedding Matplotlib In PySimpleGUI', layout, finalize=True, element_justification='center', font='Monospace 18')

Erstellen Sie als Nächstes das Diagramm, das Sie wie gewohnt einbetten möchten.

fig = plt.figure(figsize=(5, 4))
ax = fig.add_subplot(111)
ax.set_ylim(-10, 10)

Verknüpfen Sie als Nächstes das erstellte Diagramm mit dem Canvas-Element. Sie benötigen später den Rückgabewert der Funktion draw_figure.

#Assoziiere Feige mit Leinwand.
fig_agg = draw_figure(window['-CANVAS-'].TKCanvas, fig)

Die hier verwendete Funktion "draw_figure" lautet wie folgt. Grundsätzlich ist es nicht erforderlich, den Inhalt dieser Funktion zu ändern, und Sie können sie so kopieren und verwenden, wie sie ist. Um es zu verwenden, müssen Sie "FigureCanvasTkAgg" importieren, wie in der 4. Zeile des Programms gezeigt.

def draw_figure(canvas, figure):
    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

Das Einbetten ist bis zu diesem Punkt abgeschlossen.

Aktualisieren Sie die Handlung

Wenn Sie im erstellten Programm auf die Schaltfläche Hinzufügen klicken, wird dem Plot eine Sinuswelle hinzugefügt. Um das Diagramm auf diese Weise zu aktualisieren, führen Sie zuerst "ax.plot ()" und dann "fig_agg.draw ()" aus, um die Änderungen im Diagramm widerzuspiegeln.

        #Erstellen geeigneter Plotdaten
        t = np.linspace(0, 7, 100)
        afreq = np.random.randint(1, 10)
        amp = np.random.randint(1, 10)
        y = amp * np.sin(afreq * t)

        #Handlung
        ax.plot(t, y, alpha=0.4)

        #Nach Änderungen, Abb_agg.draw()Reflektieren Sie die Änderung mit.
        fig_agg.draw()

Recommended Posts

Ich möchte Matplotlib in PySimpleGUI einbetten
Ich möchte eine Variable in einen Python-String einbetten
Ich möchte in der Einschlussnotation drucken
Ich möchte Matplotlib zu einem dunklen Thema machen
Ich möchte Dunnetts Test in Python machen
Ich möchte Datetime.now in Djangos Test reparieren
Ich möchte mehrere Bilder mit matplotlib anzeigen.
Ich möchte DB-Informationen in einer Liste speichern
Ich möchte verschachtelte Dicts in Python zusammenführen
Ich möchte den Fortschritt in Python anzeigen!
Ich möchte die Farbe ändern, indem ich auf den Streupunkt in matplotlib klicke
Ich möchte in Python schreiben! (1) Überprüfung des Codeformats
Ich möchte Timeout einfach in Python implementieren
Ich möchte mit einem Knopf am Kolben übergehen
Ich möchte mich mit Backpropagation (tf.custom_gradient) (Tensorflow) selbst verwenden.
Betten Sie das Matplotlib-Diagramm in Tkinter ein
Ich möchte in Python schreiben! (2) Schreiben wir einen Test
Auch mit JavaScript möchte ich Python `range ()` sehen!
Ich möchte eine Datei mit Python zufällig testen
Ich möchte SUDOKU lösen
Ich möchte mit einem Roboter in Python arbeiten.
Ich möchte in Python schreiben! (3) Verwenden Sie Mock
Ich möchte manuell eine Legende mit matplotlib erstellen
Ich möchte R-Datensatz mit Python verwenden
Ich möchte am Ende etwas mit Python machen
Ich möchte Strings in Kotlin wie Python manipulieren!
[Django] Ich möchte mich nach einer neuen Registrierung automatisch anmelden
Ich möchte den Wörterbuchtyp in der Liste eindeutig machen
[Einführung in Pytorch] Ich möchte Sätze in Nachrichtenartikeln generieren
Ich möchte die gültigen Zahlen im Numpy-Array ausrichten
Ich möchte Python mit VS-Code ausführen können
Ich möchte eine schöne Ergänzung zu input () in Python hinzufügen
Ich wollte den AWS-Schlüssel nicht in das Programm schreiben
Ich möchte systemd grob verstehen
Ich möchte Bilder kratzen und trainieren
Ich möchte ○○ mit Pandas machen
Ich möchte Yolos Anmerkung kopieren
Ich möchte mit Python debuggen
[Linux] Ich möchte das Datum wissen, an dem sich der Benutzer angemeldet hat
Ich möchte Rails mit Rails auch in einer vagabundierenden Umgebung betreiben
LINEbot-Entwicklung möchte ich den Betrieb in der lokalen Umgebung überprüfen
[Python / AWS Lambda-Ebenen] Ich möchte nur Module in AWS Lambda-Ebenen wiederverwenden
Ich möchte eine Pipfile erstellen und im Docker wiedergeben
Ich möchte die zweite Zeile zum Spaltennamen in Pandas machen
Ich möchte den G-Test in einem Monat Tag 1 bestehen
Ich möchte die Bevölkerung jedes Landes der Welt kennenlernen.
Ich möchte Spyder an die Taskleiste anheften
Ich habe versucht, PLSA in Python zu implementieren
So unterdrücken Sie Anzeigefehler in matplotlib
Ich möchte kühl auf die Konsole ausgeben
Ich habe versucht, Permutation in Python zu implementieren
Ich möchte sie alle zusammen kratzen.
Ich möchte mit dem Reim Teil1 umgehen
Ich möchte wissen, wie LINUX funktioniert!
Ich möchte mit dem Reim part3 umgehen
Ich habe versucht, PLSA in Python 2 zu implementieren
Ich möchte ein Glas aus Python verwenden
Ich möchte Protokolle mit Python analysieren
Ich möchte mit aws mit Python spielen
Ich habe versucht, ADALINE in Python zu implementieren
Ich möchte IPython Qt Console verwenden