Home > Software engineering >  Python (Tkinter)- Selecting specific Pandas dataframe from Tkinter combobox
Python (Tkinter)- Selecting specific Pandas dataframe from Tkinter combobox

Time:02-10

I am having trouble with a Tkinter app I am making where the user would first select the dataframe from a combobox (combobox #1) which is a list of facilities within a given year (i.e., 2021 or 2022). After the dataframe is identified, the user would select a list of facilities by state in a second combobox.

If I preselect the dataframe, everything works fine. However, the user may want different years and does not want to use the Tkinter Filedialogue function. Basically, they want a dropdown menu that selects the dataframe. As I have it now, I can get it to work if I use the Input option from the command prompt, but I don't want to do that (see TEMP_SOLUTION section).

Bottom line - how can I first select the dataframe from a combobox (i.e., combobox #1) and make the state combobox use this selected dataframe as its source? Any help is appreciated.

import pandas as pd
from tkinter import ttk
import numpy as np
from tkinter import Tk
import tkinter as tk

# function to get unique values
def unique(list1):
    x = np.array(list1)
    print(np.unique(x))

def make_df(): #I'd like to make the dataframe from here, but I am having trouble
    val = n3.get()
    if val == 'df2022':
        df = df2022
    else:
        df = df2021

def on_click():
    val = n.get()
    df2 = df[ df['state'] == val ]
    print(df2)
       

#DATAFRAMES       

df2022 = pd.DataFrame({
   'id': ['1','2','3'],
   'state': ['mi','mi','oh'],
   'provname': ['abc facility','123 facility','acme facility'],
   'workdate':['1/1/2022', '1/3/2022', '6/8/2022']
})

df2021 = pd.DataFrame({
   'id': ['4','5','6'],
   'state': ['al','al','az'],
   'provname': ['jimmy state facility','mack 10 facility','heathcliff facility'],
   'workdate':['3/3/2021', '12/13/2021', '10/31/2021']
})

#TEMP SOLUTION - I don't want to do this with the command prompt, but it's all I can get to work right now
temp_idea = input('enter df2021 or df2022: ')
if temp_idea == 'df2021':
    df = df2021
else:
    df = df2022

# Create Combobox for selecting dataframe (NOT WORKING)
n3 = tk.StringVar() 
da = ttk.Combobox(window, width = 60, textvariable = n3) 
  
da['values'] = ['df2022', 'df2021']
da.grid(column = 1, row = 1, padx = 3, pady = 20)

ttk.Button(window, text = "Add Dataframe", command=make_df).grid(column = 2, 
          row = 1, padx = 3, pady = 10)

#STATE FILTER

values = ['all']   list(df['state'].unique())

window = tk.Tk() 
window.title('Combobox') 
window.geometry('600x400')
window.focus_set()
  
ttk.Label(window, text = "Main Menu",  
          foreground ="black",  
          font = ("Times New Roman", 20)).grid(row = 0, column = 1) 

#FILTER STATE - PART 1
ttk.Label(window, text = "Select the State:", 
          font = ("Times New Roman", 12)).grid(column = 0, 
          row = 2, padx = 3, pady = 29)

n = tk.StringVar() 
state = ttk.Combobox(window, width = 60, textvariable = n) 
state['values'] = sorted(list(df['state'].unique()))
state.grid(column = 1, row = 2, padx = 3, pady = 20)

ttk.Button(window, text = "OK", command=on_click).grid(column = 2, 
          row = 2, padx = 3, pady = 10)

state.current()

window.mainloop()


CodePudding user response:

You can update combobox state based on selected dataframe inside make_df(). Also you can bind on <<ComboboxSelected>> virtual event instead of using the Add Dataframe button:

import tkinter as tk
from tkinter import ttk
import pandas as pd

def make_df(event=None):
    global df
    val = n3.get()
    if val == 'df2022':
        df = df2022
    else:
        df = df2021
    # update combobox 'state'
    values = ['all']   sorted(df['state'].unique())
    state['values'] = values
    state.set('all') # select 'all' initially


def on_click():
    val = n.get()
    df2 = df if val == 'all' else df[ df['state'] == val ]
    print(df2)


#DATAFRAMES

df2022 = pd.DataFrame({
   'id': ['1','2','3'],
   'state': ['mi','mi','oh'],
   'provname': ['abc facility','123 facility','acme facility'],
   'workdate':['1/1/2022', '1/3/2022', '6/8/2022']
})

df2021 = pd.DataFrame({
   'id': ['4','5','6'],
   'state': ['al','al','az'],
   'provname': ['jimmy state facility','mack 10 facility','heathcliff facility'],
   'workdate':['3/3/2021', '12/13/2021', '10/31/2021']
})


window = tk.Tk()
window.title('Combobox')
window.geometry('600x400')
window.focus_set()

ttk.Label(window, text = "Select Dataframe:",
          font = ("Times New Roman", 12)).grid(column = 0,
          row = 1, padx = 3, pady = 29)

# Create Combobox for selecting dataframe (NOT WORKING)
n3 = tk.StringVar()
da = ttk.Combobox(window, width = 60, textvariable = n3)
da['values'] = ['df2022', 'df2021']
da.grid(column = 1, row = 1, padx = 3, pady = 20)

da.bind('<<ComboboxSelected>>', make_df)  # use virtual event instead of button

#STATE FILTER

ttk.Label(window, text = "Main Menu",
          foreground ="black",
          font = ("Times New Roman", 20)).grid(row = 0, column = 1)

#FILTER STATE - PART 1
ttk.Label(window, text = "Select the State:",
          font = ("Times New Roman", 12)).grid(column = 0,
          row = 2, padx = 3, pady = 29)

n = tk.StringVar()
state = ttk.Combobox(window, width = 60, textvariable = n)
state.grid(column = 1, row = 2, padx = 3, pady = 20)

ttk.Button(window, text = "OK", command=on_click).grid(column = 2,
          row = 2, padx = 3, pady = 10)

window.mainloop()

Note that you should create Tk() before creating other tkinter stuff.

  • Related