pythonmatplotlibtkinterpie-charttext-widget

How to create a matplotlib pie chart with input from a tkinter text widget?


I want to have a GUI with a tkinter text widget where the user can input values. After hitting the "Create!" button I want the program to open a new window and use the entered values to create a matplotlib pie chart. I tried get to get the input and store it in a variable so the program uses it to create the pie chart. But this doesn't work obviously.

As I understood so far I rather have to use an array to get this to work but:

  1. I don't know how to save the input as an array for the use of a pie chart.
  2. I don't know in which way the input has to be written into the text widget to be able to create an array. With an entry widget one can use split to specify that the single values are separated by comma, blank spaces, ... but I haven't found something similar for a text widget.
import tkinter as tk
from matplotlib import pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg

def open_pie_chart():
    inputVariable = input_text.get("1.0","end-1c")
    pie_chart_window = tk.Tk()
    frame_pie_chart = tk.Frame(pie_chart_window)
    frame_pie_chart.pack()
    vehicles = ['car', 'bus', 'bicycle', 'motorcycle', 'taxi', 'train']
    fig = plt.Figure()
    ax = fig.add_subplot(111)
    ax.pie(inputVariable, radius=1, labels=vehicles)
    chart1 = FigureCanvasTkAgg(fig,frame_pie_chart)
    chart1.get_tk_widget().pack()

root = tk.Tk()

input_frame = tk.LabelFrame(root, text="Input")
input_text = tk.Text(input_frame)

create_button = tk.Button(root, command=open_pie_chart, text="Create!")

input_frame.grid(row=1, column=0)
input_text.grid(row=1, column=0)
create_button.grid(row=2, column=0)

root.mainloop()

Solution

  • You're very close, I'm not sure where you tripped up as in your question you know the right answer (to use split()). All you have to do is setup a format that you want the user to use for the input (maybe just separate their values by commas, which is what I use for this example) and then split them on that separator. If you just want spaces, then all you need is .split() instead of what I use in the example .split(','). Then, convert those values to int and save the new inputVariable:

    import tkinter as tk
    from matplotlib import pyplot as plt
    from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
    
    root = tk.Tk()
    
    def open_pie_chart():
        inputVariable = [int(x) for x in input_text.get(1.0, "end-1c").split(',')]
        pie_chart_window = tk.Tk()
        frame_pie_chart = tk.Frame(pie_chart_window)
        frame_pie_chart.pack()
        vehicles = ['car', 'bus', 'bicycle', 'motorcycle', 'taxi', 'train']
        fig = plt.Figure()
        ax = fig.add_subplot(111)
        ax.pie(inputVariable, radius=1, labels=vehicles)
        chart1 = FigureCanvasTkAgg(fig,frame_pie_chart)
        chart1.get_tk_widget().pack()
        
    input_frame = tk.LabelFrame(root, text="Input, (format = #, #, #, #, #, #)")
    input_text = tk.Text(input_frame)
    
    create_button = tk.Button(root, command=open_pie_chart, text="Create!")
    
    input_frame.grid(row=1, column=0)
    input_text.grid(row=1, column=0)
    create_button.grid(row=2, column=0)
    
    root.mainloop()
    

    Output: enter image description here