Hello!
I am currently learning the Panel library while attempting to create something useful for my work. Below is the code, which serves as a minimum working example extracted from a larger project. My goal is to update the content of the “Graph” tab with some other data. The code reads an intake catalog file using the input file provided. After clicking a button, the file is saved to disk (credit to Marc for providing this code - thank you!). Then, I utilize the data source names from within the catalog to update and populate the widgets (this piece of code was also provided by other community fellow - thank you!). However, I am facing an issue with updating the “Graph” tab when the widget values change. Currently, my code doesn’t handle the updated widgets correctly, specifically when passing them to the plotGraph function. Does anyone know how to achieve it?
My code:
import os
import intake
import panel as pn
pn.extension()
# Widgets to choose and read the catalog file
file_input = pn.widgets.FileInput(name='Choose data catalog', accept='yml', mime_type='text/yml', multiple= False)
read_catalog = pn.widgets.Button(name='Read data catalog', button_type='primary')
# Lists that will be updated once the catalog file is read
Regs = []
StatsT = []
Exps = []
Refs = []
# Widgets that will hold the lists options (they will be also updated once the catalog is read)
WRegs = pn.widgets.Select(name='Region', options=Regs)
WStatsT = pn.widgets.Select(name='Statistic', options=StatsT)
WExps = pn.widgets.Select(name='Experiment', options=Exps)
WRefs = pn.widgets.Select(name='Reference', options=Refs)
# This logical variable is used to tell the plotGraph function if there's something to display
global loaded
loaded = False
# The plotGraph function depends on the updated widgets
# Note: at this point, I just want to output the filename instead of an actual graph
@pn.depends(WRegs, WStatsT, WExps, WRefs)
def plotGraph(WRegs, WStatsT, WExps, WRefs):
if loaded:
kname = 'test-' + WRegs + '-' + WStatsT + '-' + WExps + '-' + WRefs + '-table'
ax = pn.pane.Str(kname)
else:
ax = pn.pane.Str('Nothing to show!')
return ax
# Callback function for the 'Read data catalog' (read_catalog) button - here, all the lists and widgets are updated
def readCatalog(event):
global data_catalog, loaded
# Define the file name (this file will be saved on disk)
fname = os.path.join(os.getcwd(), 'catalog.yml')
try:
# Open the catalog file
data_catalog = intake.open_catalog(os.path.join(os.getcwd(), 'catalog.yml'))
# Update the logical variable
loaded = True
global Regs, StatsT, Exps, Refs
# For each data source in the catalog data, reads the entry name
# and get the attributes
for source in data_catalog:
attrs = source.split('-')
Regs.append(attrs[1])
if attrs[5] == 'field':
pass
else:
StatsT.append(attrs[2].upper())
Exps.append(attrs[3].upper())
Refs.append(attrs[4])
# Remove repeated elements
Regs = [*set(Regs)]
StatsT = [*set(StatsT)]
Exps = [*set(Exps)]
Refs = [*set(Refs)]
# Update the widgets
WRegs = pn.widgets.Select(name='Region', value=Regs[0], options=Regs)
WStatsT = pn.widgets.Select(name='Statistic', value=StatsT[0], options=StatsT)
WExps = pn.widgets.Select(name='Experiment', value=Exps[0], options=Exps)
WRefs = pn.widgets.Select(name='Reference', value=Refs[0], options=Refs)
Winpt.objects = pn.Column(file_input, read_catalog, WRegs, WStatsT, WExps, WRefs, width=400).objects
except IOError:
print('File ' + fname + ' does not exist!')
read_catalog.on_click(readCatalog)
Winpt = pn.Column(file_input, read_catalog, WRegs, WStatsT, WExps, WRefs, width=400)
# Function to save the catalog file on disk
@pn.depends(file_input, watch=True)
def save(value):
if file_input.value is not None:
file_input.save(os.path.join(os.getcwd(),'catalog.yml'))
print('Catalog file successfully saved!')
else:
print('Nothing to save.')
# Tab where the plogGraph should be placed
Tabs = pn.Tabs(('Graph', plotGraph), dynamic=False)
# Serve
pn.Row(Winpt, Tabs).servable()
For testing, you can grab the sample catalog from here: https://github.com/cfbastarz/teste/blob/main/catalog.yml
How it works:
Any assistance or guidance would be greatly appreciated.
Thank you!