Concat error when using float values from CDS

Hi. The below code allows a user to export and import values from a ColumnDataSource. The code works fine – however when I later concatenate a column with float values I get an error “source.data.y.concat is not a function”. Interestingly, integer values produce no error.

Below is the minimum reproducible code. To reproduce the error, use Bokeh Server, click the “Save” button, click the “Browse” button - open the file called ‘ConcatTest.csv’ and finally click the “Concat” button. In the browser console log, you will see that columns id and x will concatenate successfully as both values are integers, but column y which are float values produces the error message.
Any idea how I can fix this error or find a workaround?
Thanks in advance
Matt

from pybase64 import b64decode
import io
import pandas as pd
from bokeh.plotting import figure, show
from bokeh.io import curdoc
from bokeh.models import ColumnDataSource, CustomJS, Row, Column, DataTable, TableColumn, Button, FileInput
from bokeh.events import ButtonClick

source = ColumnDataSource({'id': [0,1],'x': [2,4], 'y': [6.676,8.354]})

columns = [TableColumn(field="id", title="id"),
            TableColumn(field="x", title="x"),
            TableColumn(field="y", title="y")]

table = DataTable(source=source, columns=columns, editable=True, width = 300, height=300)

button_save = Button(label="Save", width = 100)
button_concat = Button(label="Concat", width = 100)
button_upload = FileInput(accept=".csv")

def save_table_data(event):
    data = source.data
    df_save = pd.DataFrame.from_dict(data)
    df_save.to_csv('ConcatTest.csv', index=False)
   
button_save.on_event(ButtonClick, save_table_data)

def upload_table_data(attr, old, new):
    decoded = b64decode(new)
    file = io.BytesIO(decoded)
    df = pd.read_csv(file)
    input_header = list(df.columns.values)
    output_header = ['id', 'x', 'y']
    if input_header == output_header:
        source.data = dict(df)
    else:
        print("The input file isn't compatible.  Please check the selected file.")

button_upload.on_change('value', upload_table_data)

concat_table_columns = '''
    var id = source.data['id'].concat(source.data['id']);
    console.log(id)
    var x = source.data['x'].concat(source.data['x']);
    console.log(x)
    var y = source.data['y'].concat(source.data['y']);
    console.log(y)
'''   
button_concat.js_on_click(CustomJS(args = {'source': source}, code = concat_table_columns)) 

layout = Row(table, Column(button_save, button_upload, button_concat))

curdoc().add_root(layout)

When you load the data with Pandas, the column is a floating point numpy array (not a plain Python list). In this case Bokeh stores the data in the browser in a more efficient Float64 typed array (not a plain JS array/list). Typed arrays do not have a concat method. You can manually concatenate into a new typed array, or potentially copy the data into a plain JS array and use concat on that.

Many thanks Bryan. That makes a lot of sense.