# Panel UnknownReferenceError: can't resolve reference

**URL:** <https://discourse.holoviz.org/t/panel-unknownreferenceerror-cant-resolve-reference/8417>\
**Category:** Panel\
**Tags:** bokeh\
**Created:** [November 24, 2024, 11:03pm UTC](https://discourse.holoviz.org/t/panel-unknownreferenceerror-cant-resolve-reference/8417 "2024-11-24T23:03:07Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Cerioscha](https://discourse.holoviz.org/user_avatar/discourse.holoviz.org/cerioscha/32/4476_2.png) [@Cerioscha](https://discourse.holoviz.org/u/Cerioscha)\
**Post date:** [November 24, 2024, 11:03pm UTC](https://discourse.holoviz.org/t/panel-unknownreferenceerror-cant-resolve-reference/8417/1 "2024-11-24T23:03:08Z")

</div>

Hi, I was wondering if anyone had encountered an issue with Panel when updating multiple plots based on a user selected widget value. In my case, the user selects a date using a widget and this is used to update a Holoviews Scatter3D plot of aggregated (i.e., across a given day) data and an associated bar plot of daily data.

The code generates an error: “UnknownReferenceError: can’t resolve reference” which I believe is being triggered by Bokeh as Panel uses it. Note: despite being an error, it doesn’t crash the code but the output is verbose and interferes with the dashboard.

The Bokeh folks suggest [suppressing](https://discourse.bokeh.org/t/bug-with-deserializationerror-when-changing-content-layout-in-bokeh-3-1-1/10566/3) it but I’m unable to achieve that in my code below. Also, I’m mindful that my fundamental approach to using Panel in this dynamic way might be bad/wrong.

I’ve included a toy code example which produces the error message when the user slides the date widget across the date range. Any help/suggestions would be greatly appreciated.

Environment:

- Python version: 3.10.13
- Panel version: 1.3.1
- HoloViews version: 1.19.1
- Bokeh version: 3.3.0

Theme Park Queue Analysis Dashboard

A complete example that demonstrates:

1. Synthetic theme park data generation
2. Interactive visualization with Panel and HoloViews
3. Mixed backend usage (Plotly for 3D, Bokeh for 2D)

Requirements:

- pandas
- numpy
- holoviews
- panel
- plotly (for 3D plotting)

Tested with:

- Python version: 3.10.13
- Panel version: 1.3.1
- HoloViews version: 1.19.1
- Bokeh version: 3.3.0

Known Issue:  
When running in Jupyter, this code produces UnknownReferenceError warnings like:  
UnknownReferenceError: can’t resolve reference ‘xxx-xxx-xxx’  
The dashboard functions correctly despite these warnings.

```auto
import pandas as pd
import holoviews as hv
import panel as pn
from holoviews import opts
from datetime import datetime, timedelta
import numpy as np
import logging

# Configure logging to ignore bokeh messages
logging.getLogger('bokeh').setLevel(logging.ERROR)
logging.getLogger('jupyter_bokeh').setLevel(logging.ERROR)

# Configure Panel to be less verbose
pn.config.console_output = 'disable'
pn.config.notifications = False

# Enable both backends
hv.extension('plotly', 'bokeh')
pn.extension()

"""
This code seeks to:

1. Create a dataframe with the following columns:
    - date
    - time
    - ride
    - queue_time
2. Aggregate the dataframe to create a daily dataframe
3. Create a 3D scatter plot of the daily dataframe and an interactive bar chart
"""

# Configuration
rides = ['ride_A', 'ride_B', 'ride_C', 'ride_D']
start_date = datetime(2024, 5, 1)
end_date = datetime(2024, 9, 30)
time_slots_per_day = 32 # 4 runs/hour * 8 hours
ride_capacity = 15 # People per run

# Define base queue time ranges based on ride popularity
queue_time_ranges = {
    'ride_A': (15, 30), # Very popular
    'ride_B': (10, 20), # Moderately popular
    'ride_C': (5, 15), # Less popular
    'ride_D': (2, 10) # Least popular
}

# Generate seasonality factor (higher demand in July and August)
def seasonal_factor(date):
    if date.month in [7, 8]:
        return 1.5 # Peak summer
    elif date.month in [5, 6]:
        return 1.0 # Early summer
    else:
        return 0.8 # Post-peak

# Generate time-of-day factor
def time_of_day_factor(hour):
    if 9 <= hour < 11: # Early morning
        return 1.2
    elif 11 <= hour < 14: # Midday
        return 1.5
    elif 14 <= hour < 16: # Early afternoon
        return 1.3
    else: # Late afternoon
        return 1.0

# Configuration for rider variability
ride_mean_capacity = 12 # Average number of riders per run
ride_capacity_stddev = 3 # Standard deviation for variability

# Modify dataset generation loop
data = []
current_date = start_date

while current_date <= end_date:
    for ride in rides:
        base_min, base_max = queue_time_ranges[ride]
        for run in range(time_slots_per_day):
            hour = 9 + (run // 4) # Determine the hour of the run
            minute = (run % 4) * 15 # Calculate the exact minute
            
            season_factor = seasonal_factor(current_date)
            time_factor = time_of_day_factor(hour)
            
            # Generate queue time with added randomness
            base_time = np.random.uniform(base_min, base_max)
            queue_time = base_time * season_factor * time_factor
            queue_time = max(0, round(queue_time)) # Ensure non-negative integer
            
            # Simulate the number of riders for this run
            riders_this_run = max(0, min(ride_capacity, int(np.random.normal(ride_mean_capacity, ride_capacity_stddev))))
            
            # Create entries for all customers in this time slot
            for customer in range(riders_this_run):
                data.append({
                    'date': current_date,
                    'time': f"{hour:02d}:{minute:02d}",
                    'ride': ride,
                    'queue_time': queue_time
                })
    current_date += timedelta(days=1)

# Create a DataFrame
df_detailed = pd.DataFrame(data)

# Aggregate df_detailed to create daily_df 
daily_df = (
    df_detailed
    .groupby('date')
    .agg(
        daily_avg_queue_time=('queue_time', 'mean'), # Average queue time
        daily_customers=('queue_time', 'count') # Total number of customers
    )
    .reset_index()
)

# Create daily ride volume dataframe
daily_ride_volume = (
    df_detailed
    .groupby(['date', 'ride'])
    .agg(
        avg_queue_time=('queue_time', 'mean'),
        riders=('queue_time', 'count')
    )
    .reset_index()
)

# Convert date columns to datetime
daily_df['date'] = pd.to_datetime(daily_df['date'])
daily_df['date_num'] = daily_df['date'].astype(np.int64) // 10**6
daily_ride_volume['date'] = pd.to_datetime(daily_ride_volume['date'])

# Create interactive dataframes
idf = daily_df.interactive()
idf_rides = daily_ride_volume.interactive()

# Function to create the 3D scatter plot
def create_scatter_plot(selected_date):
    selected_date = pd.Timestamp(selected_date)
    
    daily_df['color'] = daily_df['date'].apply(
        lambda x: 'red' if x.date() == selected_date.date() else 'blue'
    )
    
    # Format dates as strings for better display
    daily_df['date_str'] = daily_df['date'].dt.strftime('%Y-%m-%d')
    
    scatter_3d_plot = hv.Scatter3D(
        daily_df,
        kdims=['date_str', 'daily_avg_queue_time', 'daily_customers'], # Use date_str instead of date_num
        vdims=['color']
    ).opts(
        width=500,
        height=400,
        color='color',
        title='Daily Queue and Customer Trends',
        xlabel='Date',
        ylabel='Average Queue Time (mins)',
        zlabel='Number of Customers',
        backend='plotly'
    )
    return scatter_3d_plot

# Function to create the bar chart
def create_bar_chart(selected_date):
    selected_date = pd.Timestamp(selected_date)
    
    # Filter data for selected date
    daily_data = daily_ride_volume[daily_ride_volume['date'].dt.date == selected_date.date()]
    
    # Create bar chart with Bokeh backend
    bars = hv.Bars(
        daily_data, 
        kdims=['ride'], 
        vdims=['riders', 'avg_queue_time']
    ).opts(
        width=500,
        height=400,
        title=f'Ride Volume for {selected_date.date()}',
        xlabel='Ride',
        ylabel='Number of Riders',
        xrotation=45,
        tools=['hover'],
        color=hv.Cycle(['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728']),
        backend='bokeh'
    )
    return bars

# Create the dashboard layout
date_slider = pn.widgets.DateSlider(
    name='Select Date',
    start=daily_df['date'].min(),
    end=daily_df['date'].max(),
    value=daily_df['date'].min(),
    step=1
)

# Create panes for the plots
scatter_pane = pn.pane.HoloViews()
bar_pane = pn.pane.HoloViews()

# Initialize the plots
initial_scatter = create_scatter_plot(date_slider.value)
initial_bars = create_bar_chart(date_slider.value)
scatter_pane.object = initial_scatter
bar_pane.object = initial_bars

# Create update function
def update_plots(event):
    scatter_plot = create_scatter_plot(event.new)
    bar_plot = create_bar_chart(event.new)
    scatter_pane.object = scatter_plot
    bar_pane.object = bar_plot

# Watch the date_slider for changes
date_slider.param.watch(update_plots, 'value')

# Create the dashboard
dashboard = pn.Column(
    pn.pane.Markdown("# Theme Park Queue Analysis Dashboard", styles={'font-size': '24px'}),
    date_slider,
    pn.Row(
        scatter_pane,
        bar_pane
    ),
    min_width=1200,
    sizing_mode='stretch_width'
)

# Display the dashboard
dashboard.servable()

```

 ![Screenshot 2024-11-24 at 22.50.52](https://discourse.holoviz.org/uploads/default/original/2X/c/c4c0f33c91d8f6fc71ab17c231ed464a006e8e50.png)

---

<div class="post-metadata">

**Author:** ![Marc](https://discourse.holoviz.org/user_avatar/discourse.holoviz.org/marc/32/24_2.png) [@Marc](https://discourse.holoviz.org/u/Marc)\
**Post date:** [November 25, 2024, 1:59pm UTC](https://discourse.holoviz.org/t/panel-unknownreferenceerror-cant-resolve-reference/8417/2 "2024-11-25T13:59:19Z")

</div>

Please do file an issue on Github about it. I also would like to get rid of error messages I should not do anything about.
