Updata data in source

Hello,

I am working on a project where I want to show an more or less empty figure and plot simple xy data upon loading a file. The way I implemented it so far is to create a dummy ColumnDataSource which I want to update with the data from the file. I manage to load my data into a data frame.

The problem I encounter is, that I am not able to pass the data frame into my source for plotting. My code is shown below:


from bokeh.models import ColumnDataSource
from bokeh.plotting import figure
from bokeh.io import show, output_notebook

from bokeh.io import curdoc
from bokeh.models.widgets import FileInput
output_notebook()
def upload_fit_data(attr, old, new):
    print("fit data upload succeeded")
    newdat=pd.read_csv(file_input.filename, delimiter=' ')
    newdat['y']=100*newdat['y']/np.max(newdat['y'])
    print(newdat)
    loaddat.data=ColumnDataSource.from_df(newdat)

    
file_input = FileInput(accept=".csv,.json,.txt")
file_input.on_change('value', upload_fit_data)

d = {'x': [0], 'y': [0]}
df=pd.DataFrame(data=d)
loaddat=ColumnDataSource(df)

def plot(doc):   
    d = {'x': [0], 'y': [99]}
    df=pd.DataFrame(data=d)
    loaddat=ColumnDataSource(df)
    doc.add_root(file_input)
    p=figure(plot_width = 950, plot_height = 600,
             x_axis_label = 'x', y_axis_label = 'y  [%]', tools=['pan,wheel_zoom, box_zoom, reset'],
             toolbar_location='below',)
    p.line(x='x', y='y', color='black', source=loaddat)
    doc.add_root(p)
show(plot)

with a data.txt as follows:


x   y
1.014   550
1.044   094
1.073   639
1.103   185
1.836   240
1.866   225
1.896   210
1.926   197
1.956   186
1.986   176

When I print my newdat everything looks fine, yet the plot does not get updated. I don’t really understand why.

Thanks in advance for your help with this rookie question!
Daniel

@d-que show normally generate Standalone HTML Output that is not persistently connected to any Python process. That output might get displayed in a notebook output cell, but the point is that real Python callbacks, i.e. on_change cannot function. If you want to use real Python call backs in response to user interactions you have two options:

1 Like

Thanks for the reply!

I am not quite sure what is the best way to go and would like a recommendation. What I want to do is this.

A small analysis program for relatively simple (scientific) xy data. It involves light number cracking and some output. I think it would be best to make it accessible as a standalone html.

For this I need to create some buttons for loading data, saving/loading “sessions” of the program. The whole handling of files is the part which gives me trouble. Is it possible to do it in an stand alone html? If yes, I guess it will involve more javascript rather than python callbacks.

Many thanks,
Daniel

@d-que You can certainly use FileInput to load the contents of a file in the standalone case, but then all of the processing would be strictly limited to JavaScript (i.e. no Pandas or NumPy available at all) since the browser has no ability to run Python code. If you need to use real Python code to do the “number cracking” you mention, then you are definitely in Bokeh server territory (the Bokeh server is the thing that would run the Python code).

Edit:

I guess for completeness I will mention that there are certainly other more obscure possibilities. E.g. a standalone document could load a file contents with FileInput and use standard ajax calls to POST the results to some separate non-Bokeh server REST API, and that server could do some processing, and then the standalone page could potentially use a Bokeh AjaxDataSource to load whatever results from that, back in to the standalone page… this sort of thing is definitely outside normal usage, though, and I can’t do more than just describe the possibility.

Hello again,

Thanks again for your support! I went down the route of a standalone html and I am able to do my “number crunching” in JS. All of this works well.

Currently, I keep all data relevant for a “session” of the program in a number of AjaxDataSources. Do I understand correctly that they correspond to JSON objects in JS?

My main problem is the input and output of files. What I would like to do are the following things: create JSON objects as save them through a JS callback on a button widget into a local and load them from a different button with a file (ideally with a window to select it popping up). As far as my understanding of JSON objects goes these things should be possible? I am just a little helpless how. As I am fairly new to JS, googling many functions raise more question than they immediately answer.

Some lines of (pseudo) code to save let’s say two AjaxDataSources in a JSON file would be super helpful. Alternatively, it would be great to point me in the right direction.

Many thanks in advance!