Saya minta maaf atas judulnya tetapi saya tidak dapat memikirkan deskripsi masalahnya yang lebih baik. Saya memiliki program berbasis Tkinter yang memiliki opsi bagi pengguna untuk menghasilkan laporan PDF yang terdiri dari ikhtisar, diikuti oleh beberapa plot detail. Saya tahu bahwa karena alasan tertentu seluruh program akan dimatikan setelah laporan PDF diselesaikan, namun baru-baru ini saya duduk untuk benar-benar mengidentifikasi penyebabnya.
Saya menemukan bahwa baris plt.close
pada plot ikhtisar awal, menyebabkan seluruh program ditutup setelah laporan pdf ditulis (yang merupakan bagian pertama yang saya tidak mengerti pastinya, jika plot.close
yang harus disalahkan mengapa seluruh modul dijalankan sampai selesai)? Kedua, mengapa hal ini bisa terjadi?
Contoh minimum yang dapat saya hasilkan (dengan data yang tidak masuk akal untuk plotnya) tercantum di bawah ini di mana jika baris yang diawali dengan # THE CULPRIT
dikomentari, instance Tk()
tetap hidup tetapi jika dibiarkan apa adanya, instance Tk()
ditutup.
import tkinter as tk
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.backends.backend_pdf import PdfPages
from pathlib import Path
class Pdf(object):
def __init__(self, master):
self.master = master
pdf = PdfPages(Path.cwd() / 'demo.pdf')
self.pdf = pdf
def plot_initial(self):
fig = plt.figure(figsize=(8,6))
fig.add_subplot(111)
mu, sigma = 0, 0.1
s = np.random.normal(mu, sigma, 1000)
count, bins, ignored = plt.hist(s, 30, density=True)
plt.plot(bins, 1/(sigma * np.sqrt(2 * np.pi)) *
np.exp( - (bins - mu)**2 / (2 * sigma**2) ),
linewidth=2, color='r')
plt.title('Overview')
plt.xlabel('X')
plt.ylabel('Y')
self.pdf.savefig(fig)
# THE CULPRIT
plt.close(fig)
def plot_extra(self):
fig = plt.figure(figsize=(8,6))
fig.add_subplot(111)
mu, sigma = 0, 0.1
s = np.random.normal(mu, sigma, 1000)
count, bins, ignored = plt.hist(s, 30, density=True)
plt.plot(bins, 1/(sigma * np.sqrt(2 * np.pi)) *
np.exp( - (bins - mu)**2 / (2 * sigma**2) ),
linewidth=2, color='r')
plt.title('Extra')
plt.xlabel('X')
plt.ylabel('Y')
self.pdf.savefig(fig)
plt.close(fig)
def close(self):
self.pdf.close()
class MVE(object):
@classmethod
def run(cls):
root = tk.Tk()
MVE(root)
root.mainloop()
def __init__(self, master):
self.root = master
tk.Frame(master)
menu = tk.Menu(master)
master.config(menu=menu)
test_menu = tk.Menu(menu, tearoff=0)
menu.add_cascade(label='Bug', menu=test_menu)
test_menu.add_command(label='PDF', command=
self.generate_pdf)
def generate_pdf(self):
pdf = Pdf(self)
pdf.plot_initial()
for i in range(0,3):
pdf.plot_extra()
pdf.close()
if __name__ == "__main__":
MVE.run()
Versi paket/basis python yang diinstal:
- Python 3.7.0
- Tkinter 8.6
- Matplotlib 2.2.3
- Angka 1.15.1
Edit
Saya telah meningkatkan ke Matplotlib 3.0.2 sesuai saran @ImportanceOfBeingErnest, namun masalahnya masih ada.
plt.close()
melakukan sesuatu yang mengakhiri sesiTk()
. Ini hanya akan terjadi jika menggunakan backend Tk. Jadi jika menggunakan backend Qt5Agg untuk pyplot, tetapi mempertahankan aplikasi tk sebagaimana adanya mungkin akan berhasil - tetapi secara umum tidak diinginkan. - person ImportanceOfBeingErnest   schedule 19.02.2019plt.close
yang mendasarinya. - person Bas Jansen   schedule 19.02.2019"Agg"
, yang tidak memerlukan perangkat QUI tambahan - person ImportanceOfBeingErnest   schedule 19.02.2019