Interact Ipywidget form with a function - python

I created a form with Ipywidget, but got some problems to "link" the chosen drop-down option with the "naïve" function f1.
import warnings
warnings.filterwarnings('ignore')
from ipywidgets import Layout, Button, Box, FloatText, Textarea, Dropdown, Label, IntSlider, widgets
form_item_layout = Layout(
display='flex',
flex_flow='row',
justify_content='space-between'
)
form_items = [
Box([Label(value='Material 1'),
Dropdown(options=crude.columns)], layout=form_item_layout),
Box([Label(value='Material 2'),
Dropdown(options=refinery['Material'].unique())], layout=form_item_layout)
]
form = Box(form_items, layout=Layout(
display='flex',
flex_flow='column',
border='solid 2px',
align_items='stretch',
width='30%'
))
def f1(material):
print(material)
w = interact(f1, material=form._trait_values['children'][1])
display(w)
I've been trying to open the methods and attributes, but got no success for while...
How can I put the selected box' item into the function?

Related

Using a Tkinter button input to pass as argument

I'm using tkinter to create an option menu, where choosing an option will call a function specific to each option. However, I'm unable to figure out exactly how to do that.
This is the code that is currently being used.
import pandas as pd
import os
import matplotlib.pyplot as plt
#below code imports file needed at the moment
import tkinter as tk
from tkinter import *
from tkinter import filedialog
import pandas as pd
import os
import matplotlib.pyplot as plt
root = tk.Tk()
root.withdraw()
file_path = filedialog.askopenfilename() #will open file from any location, does not need to be in the same place as the code script
df = pd.read_csv(file_path)
df.rename(columns={'Unnamed: 0':'Type'}, inplace=True) #renames the first unnamed column to type (drug available (DA) or not available (NA)
df.dropna(how = 'all', axis = 1, inplace = True) #drops the empty column present in each dataset, only drops it if the whole column is empty
##plotting functions for both active and inactive pokes
def ActivePokes(df):
plt.rcParams["figure.figsize"] = (12,7.5)
df.plot()
plt.xticks(range(0,len(df.Type)), df.Type)
plt.ylabel("Number of Active Pokes")
plt.xlabel("Sessions")
plt.title("Number of Active Pokes vs Drug Availability")
plt.show()
def InactivePokes(df):
plt.rcParams["figure.figsize"] = (12,7.5)
df.plot()
plt.xticks(range(0,len(df.Type)), df.Type)
plt.ylabel("Number of Inactive Pokes")
plt.xlabel("Sessions")
plt.title("Number of Inactive Pokes vs Drug Availability")
plt.show()
def show(df):
if variable == options[1]:
button[command] = ActivePokes(df)
elif variable == options[2]:
button[command] = InactivePokes(df)
else:
print("Error!")
options = [ "Choose Option",
"1. Active pokes, Drug Available and No Drug Available sessions",
"2. Inactive pokes, Drug Available and No Drug Available sessions"]
button = Tk()
button.title("Dialog Window")
button.geometry('500x90')
variable = StringVar(button)
variable.set(options[0]) #default value, might change and edit as time passes
option = OptionMenu(button, variable, *options, command = show)
option.pack()
button.mainloop()
I know the show() function is where the issue lies, but I'm not entirely sure how to rectify it.
The other comments and answer address problems with creating two Tk objects and using .get() with a StringVar.
The command = show callback is passed the string value of the item chosen. In your show( df ) when called from the Optionmenu will have df equal to one of the options. It won't be a pandas dataframe. Pure tkinter example below.
import tkinter as tk
root = tk.Tk()
root.geometry( '100x100' )
var = tk.StringVar( value = 'Option A' )
def on_choice( chosen ):
""" The callback function for an Optionmenu choice.
chosen: The text value of the item chosen.
"""
print( chosen, end = " : " )
print( ' or from the StringVar: ', var.get() )
opt_list = [ 'Option A', 'Option B', 'Option C' ]
options = tk.OptionMenu( root, var, *opt_list, command = on_choice )
options.grid()
root.mainloop()
First problem, you have created a tk instance called root, and then another one called button,why? perhaps you want button to be a tk.Button and not a tk instance? Not sure what is the intention here.
second, what is it command variable you want to change for button? (button[command]). if button where a tk.button, then perhaps you wanted to do button['command'] = ..., however, if the intention is to call the pokes functions why not calling them right away?
third problem is here:
def show(df):
if variable == options[1]:
button[command] = lambda: ActivePokes(df)
elif variable == options[2]:
button[command] = lambda: InactivePokes(df)
else:
print("Error!")
change variable for variable.get()

How do I edit a cell in flet's DataTable?

Flet's DataTable has a show_edit_icon property, but I don't know how do something when the icon is pressed.
This is an example code:
import flet as ft
def main(page: ft.Page):
page.add(
ft.DataTable(
columns=[
ft.DataColumn(ft.Text("First name")),
ft.DataColumn(ft.Text("Last name")),
],
rows=[
ft.DataRow(
cells=[
ft.DataCell(ft.Text("John"), show_edit_icon=True),
ft.DataCell(ft.Text("Smith")),
],
),
],
),
)
ft.app(target=main, view=ft.WEB_BROWSER)
I see the edit icon, but how do I connect it to some function that receives the cell that is being edited?
As per the doccumentation, In FLET data table, show_edit_icon This will only enable you to see the cell's icon. nonetheless, You must create a new function and connect it to the cell on on_tap functionality.
Note:
Add property on_tap to the the cell
implement a new function
Update the page after change inside the new function
import flet as ft
def main(page: ft.Page):
# this is the function that controls the value of the cell
# returns value on tap
def updateOnTap(e):
e.control.content.value = "Hello John"
page.update()
page.add(
ft.DataTable(
columns=[
ft.DataColumn(ft.Text("First name")),
ft.DataColumn(ft.Text("Last name")),
],
rows=[
ft.DataRow(
cells=[
ft.DataCell(ft.Text("John"), show_edit_icon=True, on_tap=updateOnTap),
ft.DataCell(ft.Text("Smith")),
],
),
],
),
)
ft.app(target=main, view=ft.WEB_BROWSER)

Button callback function not completely executed by Panel library in Python

I am currently struggling trying to use the panel library in Python, in order to build an interactive dashboard to analyze and display CSV data. My current goal is to let the user enter an initial and a final date, which will be used to filter a DataFrame once a button is pressed. However, whenever I press the button, the on_click function is not completely executed before the script stops running. The code snippet is the following:
import panel as pn
pn.extension()
def acquire_data(dateBeginning, dateEnd):
eventDF = pd.read_csv('multi.csv')
eventDF['Date']= pd.to_datetime(eventDF['Date'])
dateDF = eventDF[eventDF.upvotes > 8]
print(eventDF)
def register_dates(event, save=True):
dateBeginning = date1Picker.value
dateEnd = date2Picker.value
if dateBeginning < dateEnd:
text = pn.widgets.StaticText(name='Static Text', value='A string')
spinner = pn.indicators.LoadingSpinner(width=50, height=50, value=True, color='info', bgcolor='light')
layout = pn.Column(text, spinner, align='center')
layout.app()
print('getting in')
acquire_data(dateBeginning, dateEnd)
print('getting out')
spinner.value = False
else:
print('Not working')
#pn.pane.Alert('## Alert\nThis is a warning!')
return save
date1Picker = pn.widgets.DatePicker(name='Date Initiale', margin=25)
date2Picker = pn.widgets.DatePicker(name='Date Finale', margin=25)
button = pn.widgets.Button(name="Analyse", button_type='primary', margin=(25, 0, 20, 200), width=200)
button.on_click(register_dates)
dateLayout = pn.Row(date1Picker, date2Picker)
layout = pn.Column(dateLayout, button, width=200, align='center')
layout.app()
I was also aiming at having the first layout be replaced by the one with the spinner and the text once the button is pressed, but I haven't found anything in the doc mentioning how to do so. If anyone could give me a hint regarding these issues, that would really help me!
In def acquire_data(dateBeginning, dateEnd):
pd.read_csv('multi.csv'), pd.to_datetime(eventDF['Date'])
For start, in this function I think you forgot to import panda and your app just crash.
add: import pandas as pd
Ex:
import panel as pn
import pandas as pd

How to use a word typed in from a widget text box to search a data frame, then display the search result using python, ipywidgets?

I am just studying widget interaction in Python and Jupyter. My task is:
t=pd.DataFrame({'string':['i live here','you live in eltham','machine learning','learning english','go home','go back'],
'number':[1,3,2,3,1,2],
'word':['a','haha','runing over there','abcdefg','aaa','bye']})
import ipywidgets as widgets
from IPython.display import display
widgets.Text(
value='Hello World',
placeholder='Type something',
description='keyword:',
disabled=False
)
I need to type in some word, for example 'live', then the code will automatically search the data frame t and display all the rows with live in it.
I am seeking some hints, because I do not know where to start.
finally figure out a simple example. just put it here for someone who might need it.
t=pd.DataFrame({'string':['i live here','you live in eltham','machine learning','learning english','go home','go back','live home'],
'number':[1,3,2,3,1,2,4],
'word':['a','haha','runing over there','abcdefg','aaa','bye','hou']})
def myFUN_searchString(value,string):
s=string.split(' ')
return value in s
def myFUN_search(value):
t.loc[:,'Flag']=''
t.loc[:,'Flag']=[myFUN_searchString(value,x) for x in t.loc[:,'string']]
return t.loc[:,'Flag']
import ipywidgets as widgets
from IPython.display import display
keyword=widgets.Text(
value='electricity',
placeholder='Type something',
description='keyword:',
disabled=False
)
display(keyword)
button = widgets.Button(description="search")
display(button)
output = widgets.Output()
#output.capture()
def on_button_clicked(b):
t.loc[:,'Flag']=myFUN_search(keyword.value)
t1=t.loc[(t['Flag'])]
t1.drop(['Flag'],axis=1,inplace=True)
t1.reset_index(drop=True,inplace=True)
if t1.shape[0]>30:
t1=t1.loc[0:30]
display(t1)
button.on_click(on_button_clicked)
display(output)

How do I add selected items from combo box to a table in Jupyter widgets?

I have been trying to add items to my table using the selected item on combo box when I press the add button. Also the way I do it right now gives a faulty result that is being upside/down..
I tried multiple things but none worked. I can link the selected item from combo box to table and whenever I press to the "Add" button it links both but does not add.
from ipywidgets import Layout, interact, interact_manual, fixed
import ipywidgets as widgets
from IPython.display import display
import matplotlib.pyplot as plt
import numpy as np
Arr=['Weight','Power', '10s-Peak Power','Volume']
Combo=widgets.Dropdown(options=[Arr[0],Arr[1],Arr[2],Arr[3]],description='Requirement')
Table2=widgets.SelectMultiple(index=(0,), options = [''], rows=10,description='Desired Requirements',
disabled=False,layout=Layout(width ='450px'))
button = widgets.Button(description="Add",icon='check')
output = widgets.Output()
def on_button_clicked(b):
with output:
d=widgets.link((Combo,'value'),(Table2,'options'))
d.unlink()
button.on_click(on_button_clicked)
display(button,Combo,Table2)
I want my table to be filled with the context inside combo box as the "Add" button is being pressed. Doing so, combo box's specific item should be removed from the combo box list and added to the table.
I think you need something like this for your on_button_clicked function:
def on_button_clicked(b):
new_option = Combo.value
Table2.options = (*Table2.options, new_option)
Combo.options = (o for o in Combo.options if o!=new_option)
Basically this edits options for Table2 to include the thing currently selected in Combo and edits options for Combo to exclude it.

Categories