在Tkinter标签中嵌入Matplotlib绘图



我刚刚用python把这个基本的退休储蓄计算器组装在一起。当这起作用时,我有几个问题:

  1. 有没有一种方法可以直接嵌入绘图,即不将其保存为PNG,然后再次加载
  2. 第30行读取img.image = render。虽然我知道这会更新第29行上定义的标签的图像属性,但我很困惑为什么需要这一行,因为我们已经在第29行本身调用了image = render。为什么两次
from tkinter import *
import pandas as pd
import matplotlib.pyplot as plt
from PIL import ImageTk, Image
def generate_plot():
rate = float(entry_1.get())
years_saving = int(entry_2.get())
initial_savings = float(entry_3.get())
yearly_contribution = float(entry_4.get())
model = pd.DataFrame({'time': range(years_saving)})
model['simple_exp'] = [initial_savings*rate**year for year in model['time']]
model['yearly_invest'] = model['simple_exp'] + [yearly_contribution*(rate**year - 1)/(rate-1) for year in model['time']]
final = model['yearly_invest'].sort_values(ascending= False).iloc[0]
label_5 = Label(frame, text=f"You would have saved INR {final} by retirement")
label_5.grid(row=0, column=0)
plt.plot(model['time'], model['yearly_invest'])
plt.title('Retirement Savings')
plt.xlabel('Time in Years)')
plt.ylabel('INR (Lacs)')
plt.savefig('plot.png')
load = Image.open('plot.png')
render = ImageTk.PhotoImage(load)
img = Label(frame, image = render)
img.image = render
img.grid(row=1, column=0)   
# my_label = Label(frame, image = my_img)
# my_label.grid(row=1, column=0)
# img = ImageTk.PhotoImage(Image.open('plot.png'))
# img_label = Label(frame, image = img)
# img_label.grid(row=1, column=0)
root = Tk()
label_1 = Label(root, text = 'INTEREST RATE(%)')
label_2 = Label(root, text = 'NUMBER OF YEARS IN SAVINGS')
label_3 = Label(root, text = 'INITIAL CORPUS (INR LACS)')
label_4 = Label(root, text = 'YEARLY CONTRIBUTION (INR LACS')
frame = Frame(root, width=300, height=300)
button = Button(root, text="GENERATE PLOT", command = generate_plot, padx = 5, pady=5)
entry_1 = Entry(root)
entry_2 = Entry(root)
entry_3 = Entry(root)
entry_4 = Entry(root)
label_1.grid(row=0, column=0, pady=5, padx=5)
entry_1.grid(row=0, column=1, pady=5, padx=5)
label_2.grid(row=1, column=0, pady=5, padx=5)
entry_2.grid(row=1, column=1, pady=5, padx=5)
label_3.grid(row=2, column=0, pady=5, padx=5)
entry_3.grid(row=2, column=1, pady=5, padx=5)
label_4.grid(row=3, column=0, pady=5, padx=5)
entry_4.grid(row=3, column=1, pady=5, padx=5)
button.grid(row=4,column=0, columnspan=2, pady=20, padx=5)
frame.grid(row=5, column=0, columnspan = 2, padx = 5, pady = 5)
root.mainloop()

您可以尝试使用BytesIO:保存到流

from tkinter import *
from io import BytesIO
import pandas as pd
import matplotlib.pyplot as plt
from PIL import ImageTk, Image
def generate_plot():
rate = float(entry_1.get())
years_saving = int(entry_2.get())
initial_savings = float(entry_3.get())
yearly_contribution = float(entry_4.get())
model = pd.DataFrame({'time': range(years_saving)})
model['simple_exp'] = [initial_savings*rate**year for year in model['time']]
model['yearly_invest'] = model['simple_exp'] + [yearly_contribution*(rate**year - 1)/(rate-1) for year in model['time']]
final = model['yearly_invest'].sort_values(ascending= False).iloc[0]
label_5 = Label(frame, text=f"You would have saved INR {final} by retirement")
label_5.grid(row=0, column=0)
plt.plot(model['time'], model['yearly_invest'])
plt.title('Retirement Savings')
plt.xlabel('Time in Years)')
plt.ylabel('INR (Lacs)')
img_data = BytesIO()
plt.savefig(img_data)
load = Image.open(img_data)
render = ImageTk.PhotoImage(load)
img = Label(frame, image = render)
img.image = render # This is needed to keep a reference to the image, see the link below
img.grid(row=1, column=0)   
# my_label = Label(frame, image = my_img)
# my_label.grid(row=1, column=0)
# img = ImageTk.PhotoImage(Image.open('plot.png'))
# img_label = Label(frame, image = img)
# img_label.grid(row=1, column=0)
root = Tk()
label_1 = Label(root, text = 'INTEREST RATE(%)')
label_2 = Label(root, text = 'NUMBER OF YEARS IN SAVINGS')
label_3 = Label(root, text = 'INITIAL CORPUS (INR LACS)')
label_4 = Label(root, text = 'YEARLY CONTRIBUTION (INR LACS')
frame = Frame(root, width=300, height=300)
button = Button(root, text="GENERATE PLOT", command = generate_plot, padx = 5, pady=5)
entry_1 = Entry(root)
entry_2 = Entry(root)
entry_3 = Entry(root)
entry_4 = Entry(root)
label_1.grid(row=0, column=0, pady=5, padx=5)
entry_1.grid(row=0, column=1, pady=5, padx=5)
label_2.grid(row=1, column=0, pady=5, padx=5)
entry_2.grid(row=1, column=1, pady=5, padx=5)
label_3.grid(row=2, column=0, pady=5, padx=5)
entry_3.grid(row=2, column=1, pady=5, padx=5)
label_4.grid(row=3, column=0, pady=5, padx=5)
entry_4.grid(row=3, column=1, pady=5, padx=5)
button.grid(row=4,column=0, columnspan=2, pady=20, padx=5)
frame.grid(row=5, column=0, columnspan = 2, padx = 5, pady = 5)
root.mainloop()

参考:为什么我的Tkinter图像没有出现?

最新更新