argcv
November 17, 2022, 6:45am
#1
Hi,
I posted a question on stackoverflow: python 3.x - How do I add loading indicator to a holoviz panel which is displayed while some computation is done? - Stack Overflow
I just discovered this community, and re-posting the same here. Below are the question details:
I am working on a project which uses the holoviz panel for display. The panel has a button which does some heavy computation on click and displays result after a few seconds. How do I modify the code such that I get a loading indicator(spinner) while data is being fetched? I probably need to add loading_indicator = True
somewhere(pass as parameter), but haven’t had any success so far. Is there an alternate way? Minimal code:
import panel as pn
import pandas as pd
pn.extension()
submit_button = pn.widgets.Button(name='Submit', button_type='primary', width = 180)
radio_buttons_group = pn.widgets.RadioButtonGroup(options=['Ying', 'Yang'], button_type='default')
outer_col = pn.Column(radio_buttons_group, submit_button)
@pn.depends(submit_button.param.clicks, watch=True)
def display_result(event):
if(len(outer_col) > 2):
outer_col.pop(len(outer_col)-1)
if(radio_buttons_group.value == 'Ying'):
ying_view()
else:
yang_view()
def ying_view():
#some heavy computation
outer_col.append(pd.DataFrame({'col1': [1, 2], 'col2': [3, 4]})) #sample
def yang_view():
#some heavy computation
outer_col.append(pd.DataFrame({'col1': [5, 6], 'col2': [7, 8]})) #sample
outer_col
I just want to include the (bare minimum) loading indicator. Nothing fancy please.
Thanks in advance!
1 Like
Marc
November 17, 2022, 7:34am
#2
You can use pn.panel(..., loading_indicator=True)
as below.
import panel as pn
import pandas as pd
import time
pn.extension()
submit_button = pn.widgets.Button(name='Submit', button_type='primary', width = 180)
radio_buttons_group = pn.widgets.RadioButtonGroup(options=['Ying', 'Yang'], button_type='default')
@pn.depends(submit_button.param.clicks)
def result(event):
if submit_button.clicks<1:
return "Choose an option and click submit"
if(radio_buttons_group.value == 'Ying'):
return ying_view()
else:
return yang_view()
def ying_view():
#some heavy computation
time.sleep(0.5)
return pd.DataFrame({'col1': [1, 2], 'col2': [3, 4]}) #sample
def yang_view():
#some heavy computation
time.sleep(0.5)
return pd.DataFrame({'col1': [5, 6], 'col2': [7, 8]}) #sample
outer_col = pn.Column(radio_buttons_group, submit_button, pn.panel(result, loading_indicator=True))
outer_col.servable()
Explore the live app here (Note: time.sleep is not working in Webassembly).
3 Likes
argcv
November 17, 2022, 8:35am
#3
That’s very kind of you Marc. I really appreciate the answer. Follow-up:
I can’t get rid of the line
if(len(outer_col) > 2):
outer_col.pop(len(outer_col)-1)
I understand that you provided a sanity check(clicks < 1
), but it is already accounted for somewhere else. Is there a way we can work around this as well(keeping this piece of code intact instead of placing the sanity check)?
Thanks a lot Marc
argcv
December 14, 2022, 8:45am
#4
Here’s another solution by @carl which might be helpful for someone
import panel as pn
import pandas as pd
pn.extension()
submit_button = pn.widgets.Button(name='Submit', button_type='primary', width = 180)
radio_buttons_group = pn.widgets.RadioButtonGroup(options=['Ying', 'Yang'], button_type='default')
outer_col = pn.Column(radio_buttons_group, submit_button)
#added loading widget indicator
loading = pn.indicators.LoadingSpinner(value=False, width=100, height=100,visible=False)
#function to activate / deactivate loading widget
def load_display(x):
if(x=='on'):
loading.value=True
loading.visible=True
if(x=='off'):
loading.value=False
loading.visible=False
@pn.depends(submit_button.param.clicks, watch=True)
def display_result(event):
if(len(outer_col) > 2):
outer_col.pop(len(outer_col)-1)
if(radio_buttons_group.value == 'Ying'):
ying_view()
else:
yang_view()
def ying_view():
#some heavy computation
load_display('on') #call loading widget with 'on' to activate
time.sleep(0.5)
outer_col.append(pd.DataFrame({'col1': [1, 2], 'col2': [3, 4]})) #sample
load_display('off')
def yang_view():
#some heavy computation
load_display('on')
time.sleep(0.5)
outer_col.append(pd.DataFrame({'col1': [5, 6], 'col2': [7, 8]})) #sample
load_display('off')
x = pn.Row(outer_col, loading)
x.show()