3

I am new to Python and I want to create an interactive dropdown list from an ipywidget. The main purpose is to update the dropdown list based on two other widgets. In the code below, the widget plotType will be updated based on the input from the widgets headers_x and headers_y (both refer to the dataframe columns selected for plotting). If both headers_x and headers_y have the Select option, then the plotType needs to show "Make selection". But if the headers_x and headers_y have other options selected (columns from the dataframe), then the plotType needs to change accordingly. If the headers_x and headers_y are both numeric, then the plotType needs to show: numericVsNumeric, but if headers_x is categorical and headers_y is numeric, then plotType needs to show 'catergoricalVsNumeric' I have attempted my solution as follows, but the options in the plotType widget do not update. Any help is much appreciated. Thank you.

from ipywidgets import *
import seaborn.apionly as sns
df = sns.load_dataset('iris')

#identifies the columns in the dataframe
df_cols = list(df.columns.values)
df_cols.insert(0, 'Select')
str_cols = list(df.select_dtypes(include=['object']).columns.values)
str_cols.insert(0, 'Select')

#plot function
def set_plot(headers_x, headers_y, plotType):
    data = df
    #plotting functions to be added

#function to specify the type of plot based on users input
def set_plotType():
    data = df
        #If no selection has been made
    if headers_x.value == 'Select' and headers_y.value == 'Select':
        init = list(['Make Selection'])
    else:
        #if x and y are both numeric
        if data[headers_x.value].dtype == np.float and data[headers_y.value].dtype == np.float:
            init = list(['NumericVsNumeric'])
            #if x is categorical and y is numeric
        elif data[headers_x.value].dtype == np.object and data[headers_y.value].dtype == np.float:
            init = list(['CategoricalVsNumeric'])

    return init


#define widgets
headers_x = widgets.Dropdown(
        options=df_cols,
        value=df_cols[0],
        description='X'
    )

headers_x.set_title  = 'headers_x'

headers_y = widgets.Dropdown(
        options=df_cols,
        value=df_cols[0],
        description='Y'
    )

headers_y.set_title  = 'headers_y'

plotType = widgets.Dropdown(
        options=set_plotType(),
        #value=df_cols[0],
        description='Plot Type'
    )

plotType.set_title  = 'plotType'


#interact function
interact(set_plot, headers_x = headers_x, headers_y = headers_y, plotType = plotType)

1 Answer 1

6

I achieved this by using observe. This means whenever your top two drop down options change, they will run the set_Plottype function.

I changed your headers.x AND headers.y to an OR, as you need both defined.

I also gave you a third option for when x is numeric and y is categorical.

from ipywidgets import *
import numpy as np
import seaborn.apionly as sns
df = sns.load_dataset('iris')

#identifies the columns in the dataframe
df_cols = list(df.columns.values)
df_cols.insert(0, 'Select')
str_cols = list(df.select_dtypes(include=['object']).columns.values)
str_cols.insert(0, 'Select')

#plot function
def set_plot(headers_x, headers_y, plotType):
    data = df
    #plotting functions to be added

#function to specify the type of plot based on users input
def set_plotType(_):
    data = df
        #If no selection has been made
    if headers_x.value == 'Select' or headers_y.value == 'Select':
        plotType.options = list(['Make Selection'])
    else:
        #if x and y are both numeric
        if data[headers_x.value].dtype == np.float and data[headers_y.value].dtype == np.float:
            plotType.options = list(['NumericVsNumeric'])
            #if x is categorical and y is numeric
        elif data[headers_x.value].dtype == np.object and data[headers_y.value].dtype == np.float:
            plotType.options = list(['CategoricalVsNumeric'])
        elif data[headers_x.value].dtype == np.float and data[headers_y.value].dtype == np.object:
            plotType.options = list(['NumericalVsCategoric'])



#define widgets
headers_x = widgets.Dropdown(
        options=df_cols,
        value=df_cols[0],
        description='X'
    )

headers_x.set_title  = 'headers_x'

headers_y = widgets.Dropdown(
        options=df_cols,
        value=df_cols[0],
        description='Y'
    )

headers_y.set_title  = 'headers_y'

plotType = widgets.Dropdown(
        options=[],
        description='Plot Type'
    )

headers_x.observe(set_plotType)
headers_y.observe(set_plotType)


#interact function
interact(set_plot, headers_x = headers_x, headers_y = headers_y, plotType = plotType)

enter image description here

Sign up to request clarification or add additional context in comments.

1 Comment

This is exactly what I was looking for. Thank you very much, @ac24. I really appreciate it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.