Exe stürzt unter Verwendung von tkinter und matplotlib ab

Fragen zu Tkinter.
Antworten
elias123
User
Beiträge: 3
Registriert: Mittwoch 2. September 2020, 11:25

Hallo Zusammen,

ich bin neu in diesem Forum und schreibe gerade an meiner Masterarbeit. Ich habe ein Programm geschrieben, das mit tkinter 8.6 eine GUI besitzt und unter anderem mit matplotlib Graphen zeichnet. Dieses Programm soll als .exe ausgeführt werden. Dazu verwende ich pyinstaller 3.6.
Führe ich das Programm in pycharm 2019.3.3 aus, funktioniert es einwandfrei. Das Plotten der Graphen funktioniert auch, wenn ich die Funktion ohne tkinter als .exe ausführe. Allerdings stürzt die .exe jedes Mal (ohne Fehlermeldung) ab wenn ich es mit der GUI starten will. Ich verwende Python 3.7

Hier ist ein Minimalbeispiel, welches den selben Fehler besitzt. Ich vermute, dass der Fehler an matplotlib liegt. Ich habe bereits die Versionen 3.0.3 und 3.3.1 ausprobiert und immer den selben Fehler erhalten.

Code: Alles auswählen

import tkinter as tk
from tkinter import messagebox, ttk, Listbox, Scrollbar, filedialog
from math import sin, cos, pi, sqrt, radians
import numpy as np
import openpyxl
from openpyxl import Workbook
from matplotlib import patches as patches
from matplotlib import pyplot as plt
import os


def test():
    alpha_res = 1
    m = 20
    x = np.linspace(0, 200, 200) # x axis of graph with 200 points
    # calculation of resolution (min and max)
    R_lat_min = x * np.tan(np.deg2rad(alpha_res))
    R_lat_max = x * (np.tan(np.deg2rad(m * alpha_res)) - np.tan(np.deg2rad((m - 1) * alpha_res)))
    R_max = 200 * (np.tan(np.deg2rad(m * alpha_res)) - np.tan(np.deg2rad((m - 1) * alpha_res)))
    plt.title('Lateral Resolution of ')
    plt.xlabel('Radial Direction [m]')
    plt.ylabel('Lateral Resolution [m]')
    plt.plot(x, R_lat_min, label='Minimum Lateral Resolution')
    plt.plot(x, R_lat_max, label='Maximum Lateral Resolution')
    lgd = plt.legend(loc='best')
    plt.xlim(0, 200 + 10)
    plt.ylim(0, R_max + 0.5)
    my_file = 'Lateral Resolution.pdf'
    my_path = 'C:\\Users\\u24e46\\test'
    plt.savefig(os.path.join(my_path, my_file), bbox_extra_artists=(lgd,),
        bbox_inches='tight') #saves figure
    plt.close()

fenster = tk.Tk()
Button = tk.Button(fenster,text='test',command=test)
Button.grid(row=1,column=1)
button2 = tk.Button(fenster,text='schliessen',command=fenster.destroy)
button2.grid(row=1, column=2)
fenster.mainloop()
Hatte jemand schon mal das selbe Problem und kann mir mit der Lösung helfen?
Benutzeravatar
sparrow
User
Beiträge: 4540
Registriert: Freitag 17. April 2009, 10:28

Was heißt denn "es stürzt ohne Fehlermeldung ab"?
Wie startest du das Programm (also die .exe) denn? Hoffentlich aus der Kommandozeile.
elias123
User
Beiträge: 3
Registriert: Mittwoch 2. September 2020, 11:25

Ich starte es aus der Kommandozeile.
Es heißt, dass sich das Programm schließt. Allerdings habe ich festgestellt, dass die Graphik bei der Betätigung des Buttons test schon noch erstellt wird. Das Programm schließt sich somit erst nach dem Ausführen der Funktion. Es wird dabei keine Fehlermeldung in der Kommandozeile ausgegeben
Benutzeravatar
__blackjack__
User
Beiträge: 14085
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@elias123: Was passiert wenn Du das `plt.close()` weg lässt?
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
elias123
User
Beiträge: 3
Registriert: Mittwoch 2. September 2020, 11:25

@__blackjack__: das löst das Problem! Danke!
Allerdings bekomme ich dann ein anderes Problem. Wenn ich versuche mehr als 20 Figures zu erstellen, kommt folgende Fehlermeldung:
RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (`matplotlib.pyplot.figure`) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam `figure.max_open_warning`).
Gibt es eine weitere Möglichkeit, um die Graphiken zu schließen?
Benutzeravatar
__blackjack__
User
Beiträge: 14085
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@elias123: Die saubere Lösung wäre es wahrscheinlich nicht die API mit den Funktionen die auf impliziten globalen Graphen operieren zu verwenden. Und/oder explizit ein Backend auszuwählen das *nicht* Tk verwendet.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Antworten