Adding data to a blank columndatasource based on a line graph I clicked

Hello everyone,

I’m trying to update a blank datatable based on whatever point on the line graph I clicked using a python callback. I managed to get the code to execute, however the source2.change.emit() function doesn’t work. It says that ColumnDataSource has no change attribute. Does anyone know the proper/alternative way to do this in a python callback?

Here is my current code:

def bkapp(doc)
    # this is kinda pseudocode, I'm not including the actual data
    source = ColumnDataSource(data=data)
    source2 = ColumnDataSource(data=dict(x=[], y=[]))

    p = figure()
    p.line(source=source, x='x_values', y='y_vlaues')

    datatable = DataTable(source=source2)

    def callback(event):
        # the x axis is a unix timestamp value
        date = datetime.datetime.fromtimestamp(event.x / 1000)
        source_x = source.data['x_values']
        # rounds to the nearest 3 hours
        rounded_date = round_nearest_hours(date)
        
        sected_index = int

        for i in range(len(source_x)):
            if rounded_date.date() == source_x[i].date():
                if rounded_date.time() == source_x[i].date():
                    source2 = data # Calling a remote function here that returns a ColumnDataSource

        source2.change.emit()

    p.on_event('tap', callback)
    doc.add_root(column(p, datatable))
    
show(bkapp)

It’s hard to offer specific advice since the code is not a complete Minimal Reproducible Example, but I will mention a few general things.

  • change.emit etc only exist on the JavaScript side. There are not Python versions of those methods because they are not needed
  • If you want to change all the data in a CDS you should set the .data property if the existing source (don’t create an entirely new CDS, that is a very heavyweight operation)
    source.data = new_data_dict
    
    There are lots of examples of this pattern in the docs and examples repo.

Lastly, setting source2 in your code the way you are doing would never have any effect. You are effectively updating a module/global var to a new value which does not change anything that might be configured with the old value (that’s just how Python works)

Hi Bryan,

Sorry I’m unable to give a minimal reproducible example. I can’t due to external reasons out of my control.
However, the general things you mentioned were quite helpful! Instead of doing a source2 = another CDS i used the .data like you suggested and set it to the dataframe. This actually made the datatable update with rows. However for some reason it just shows empty rows and 1 long column. Any clue what’s happening here?

And I have read the documentation a lot trying to get this working but I guess I just didn’t fully understand it. So my bad.

Nevermind. I declared the datatable with the columns set and now it works! Thanks for the help bryan

1 Like