Panel datepicker datetime error

Hello,

I’m using panel.datepicker() to pass on datetimes to an xarray object. When I select a new date in an app, I convert the Date value passed from datepicker to a datetime object. This works in the app appropriately, but I keep getting this error in my notebook…

AttributeError: 'Date' object has no attribute 'year'

Here is some example code:

@pn.depends(dataset.param.value, dateVal.param.value)
def make_plot(dataset, dateVal):
___ sDate = datetime(dateVal.year, dateVal.month, dateVal.day)

Any ideas on how to get rid of this error? Thank you!

To be able to reproduce any issues it is always useful to have a full reproducible example including the versions of the libraries you are using.

Sorry about that! I discovered further that this error is occurring because of the way I’m using the panel button widget.

Here is some reproducible code.

# Python 3.7, anaconda dist
from datetime import date, datetime, timedelta
import panel as pn #version 0.8.3
import xarray as xr #version 0.11.3
import hvplot.xarray #version 0.5.2
import hvplot.pandas #version 0.5.2
import geoviews as gv #version 1.7.0
gv.extension('bokeh')

# read in the refET dataset
dsRefET = xr.open_dataset("http://basin.ceoe.udel.edu/thredds/dodsC/DEOSRefET.nc")

# declare dataset list
datasets = ['RefET']

# generate panel widgets
dataset = pn.widgets.Select(name='Dataset', options=datasets, value=datasets[0])
dateVal = pn.widgets.DatePicker(name='Start Date', value=(date.today() + timedelta(days=-1)))

@pn.depends(dataset.param.value, dateVal.param.value)
def make_plot(dataset, dateVal):
    # Convert Date object to Datetime to work-around Date object / timedelta error panel was showing
    sDate = datetime(dateVal.year, dateVal.month, dateVal.day)
    # create title string 
    quad_title = str("DEOS " + str(dataset) + "    Start Date : " +
                    datetime.strftime(sDate + timedelta(days=-1), "%Y-%m-%d"))
    # select data
    df = dsRefET.sel(time=[sDate], method='nearest')         
    # create quadmesh plot
    chart = df.refET.hvplot.quadmesh(x='longitude', y='latitude',project=True,geo=True,
                               title=quad_title, rasterize=True, dynamic=False)
    
    return chart

# create button to update plot
def update(event):
    dashboard[1].object = make_plot(dataset.param.value, dateVal.param.value)

generate_button = pn.widgets.Button(name='Plot', button_type='primary')
generate_button.on_click(update)

    
dashboard = pn.Row(pn.Column(dataset, dateVal, generate_button), make_plot)
dashboard.show()

`

I’d recommend updating to Panel 0.9.5 at this point.

Just updated to v0.9.5, still getting the same error - AttributeError: 'Date' object has no attribute 'year'

I think it’s due to the way I’m using generate_button here. Am I defining something wrong when I try to update the plot via pn.widgets.Button ?

def update(event):
    dashboard[1].object = make_plot(dataset.param.value, dateVal.param.value)

generate_button = pn.widgets.Button(name='Plot', button_type='primary')
generate_button.on_click(update)

This doesn’t seem correct to me, I think you just want:

make_plot(dataset.value, dateVal.value)

That worked! Thank you, I figured it was something simple.

I’m now receiving a new error:

AttributeError: 'HoloMap' object has no attribute '_dinfo'

Below is the updated code…

# Python 3.7, anaconda dist
from datetime import date, datetime, timedelta
import panel as pn #version 0.9.5
import xarray as xr #version 0.11.3
import hvplot.xarray #version 0.5.2
import hvplot.pandas #version 0.5.2
import geoviews as gv #version 1.8.1
gv.extension('bokeh')

# read in the refET dataset
dsRefET = xr.open_dataset("http://basin.ceoe.udel.edu/thredds/dodsC/DEOSRefET.nc")

# declare dataset list
datasets = ['RefET']

# generate panel widgets
dataset = pn.widgets.Select(name='Dataset', options=datasets, value=datasets[0])
dateVal = pn.widgets.DatePicker(name='Start Date', value=(date.today() + timedelta(days=-1)))

@pn.depends(dataset.param.value, dateVal.param.value)
def make_plot(dataset, dateVal):
    # Convert Date object to Datetime to work-around Date object / timedelta error panel was showing
    sDate = datetime(dateVal.year, dateVal.month, dateVal.day)
    # create title string 
    quad_title = str("DEOS " + str(dataset) + "    Start Date : " +
                    datetime.strftime(sDate + timedelta(days=-1), "%Y-%m-%d"))
    # select data
    df = dsRefET.sel(time=[sDate], method='nearest')         
    # create quadmesh plot
    chart = df.refET.hvplot.quadmesh(x='longitude', y='latitude',project=True,geo=True,
                               title=quad_title, rasterize=True, dynamic=False)
    
    return chart

# create button to update plot
def update(event):
    dashboard[1].object = make_plot(dataset.value, dateVal.value)

generate_button = pn.widgets.Button(name='Plot', button_type='primary')
generate_button.on_click(update)

    
dashboard = pn.Row(pn.Column(dataset, dateVal, generate_button), make_plot)
dashboard.show()

So some comments, first of all you seem to be using multiple patterns to update your plot here, you should either use a param.depends pattern or an explicit callback pattern. Since you’ve already added the button and the callback I’d suggest just doing the following:

# Python 3.7, anaconda dist
from datetime import date, datetime, timedelta
import panel as pn #version 0.9.5
import xarray as xr #version 0.11.3
import hvplot.xarray #version 0.5.2
import hvplot.pandas #version 0.5.2
import geoviews as gv #version 1.8.1
gv.extension('bokeh')

# read in the refET dataset
dsRefET = xr.open_dataset("http://basin.ceoe.udel.edu/thredds/dodsC/DEOSRefET.nc")

# declare dataset list
datasets = ['RefET']

# generate panel widgets
dataset = pn.widgets.Select(name='Dataset', options=datasets, value=datasets[0])
dateVal = pn.widgets.DatePicker(name='Start Date', value=(date.today() + timedelta(days=-1)))

# Note how I've removed the decorator
def make_plot(dataset, dateVal):
    # Convert Date object to Datetime to work-around Date object / timedelta error panel was showing
    sDate = datetime(dateVal.year, dateVal.month, dateVal.day)
    # create title string 
    quad_title = str("DEOS " + str(dataset) + "    Start Date : " +
                    datetime.strftime(sDate + timedelta(days=-1), "%Y-%m-%d"))
    # select data
    df = dsRefET.sel(time=[sDate], method='nearest')         
    # create quadmesh plot
    chart = df.refET.hvplot.quadmesh(x='longitude', y='latitude',project=True,geo=True,
                               title=quad_title, rasterize=True, dynamic=False)
    
    return chart

# create button to update plot
def update(event):
    dashboard[1].object = make_plot(dataset.value, dateVal.value)

generate_button = pn.widgets.Button(name='Plot', button_type='primary')
generate_button.on_click(update)

# Note how I explicitly call make_plot now
dashboard = pn.Row(pn.Column(dataset, dateVal, generate_button),
                   make_plot(dataset.value, dateVal.value))
dashboard.show()

I’m not exactly sure where the error you were reporting is coming from though, something may have redefined dataset in the namespace.

That seems to have gotten rid of the error! Thanks for sorting out the pattern mixup, that was something I wasn’t understanding. Thank you for the help and for all the dev work with Holoviz, I love this suite of modules!

1 Like