简体   繁体   English

将 Matplotlib plot 嵌入 Tkinter ZB021DF6AAC4654C454FZ6C77646E745

[英]Embedding Matplotlib plot inside Tkinter Label

I just put together this basic retirement savings calculator using python.我刚刚使用 python 将这个基本的退休储蓄计算器放在一起。 While this works, I had a couple of questions:虽然这有效,但我有几个问题:

  1. Is there a way to embed the plot directly, ie without saving it as a PNG and then loading it again?有没有办法直接嵌入 plot ,即不将其保存为 PNG 然后再次加载?
  2. Line 30 reads img.image = render .第 30 行读取img.image = render While I understand that this updates the image attribute for the label defined on line 29 , I am confused why this line is required, since we already call out image = render on line 29 itself.虽然我知道这会更新第29 行定义的 label 的图像属性,但我很困惑为什么需要这一行,因为我们已经在第 29 行本身调用了image = render Why twice?为什么两次?
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()

You can try saving to a stream using BytesIO :您可以尝试使用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()

Reference: Why do my Tkinter images not appear?参考: 为什么我的 Tkinter 图像没有出现?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM