☰Read-only archive⌕
Looking for help with Bokeh?

This is a read-only archive. Ask questions and join the conversation on GitHub.

Visit Community Support on GitHub →
Archived discussions · Captured October 28, 2026

Issues about empty row in Table when indices are selected

Community Supportcustomjsserverbokeh
Charlie
Charlie

Hello,

I have the following code with this table but I am not able to make that only the selected rows of the selected points in the chart appear, that is to say, when I select points, the blank rows of unselected points do not appear.

Would it be possible that these rows do not appear?

Something aesthetic but I would like to know if it is possible to have the values that appear in the table centered in some way.

Thanks in advance.

import pandas as pd
import numpy as np

from bokeh.models import (ColumnDataSource,  DataTable, TableColumn
                         )

from bokeh.plotting import figure, curdoc, show
from bokeh.layouts import  row




x = np.random.sample(10)
y = np.random.sample(10)
z = np.random.sample(10)

l = ['P'+str(n) for n in range(len(z))]
c = ['skyblue']*len(x)
cl= ['c1']*4 + ['c2']*3 + ['c3']*3

dataf = pd.DataFrame({'Var1': x, 'Var2': y, 'Var3': z, 'Label': l, 'color': c, 'class': cl} )



source = ColumnDataSource(data=dict(x=dataf['Var1'],
                                    y=dataf['Var2'],
                                    z=dataf['Var3'],
                                    l=dataf['Label'],
                                    c=dataf['color']
                                   ))

p1 = figure(plot_width=800, plot_height=700,
            tools="tap,pan,lasso_select,wheel_zoom,save,reset",
            toolbar_location="above",
           )


p1.circle(x="x", y="y",color='c' ,fill_alpha=0.8 ,source=source, size=10,
           selection_line_color="darkblue")

columns = [TableColumn(field=n,title=n) for n in ['Var1','Var2','Var3','Label']]
table = DataTable(source=source,columns=columns, width=800, height=300)

    
def update_table(data):
    table.source = ColumnDataSource(data)
    
        
def selection_change(attrname, old, new):
    data = dataf.copy()
    selected = source.selected.indices
    if selected:
        data = data.iloc[selected, :]
        
    update_table(data)


source.selected.on_change('indices', selection_change) 

display = row(p1,table)

curdoc().add_root(display)
⌁   Link to post
crashMOGWAI
crashMOGWAI

Since you are sharing the same source the table is hanging onto the elements that are still in the cds, just not selected. You should be able to pass a CDSView to the table to get rid of the extra rows.

Something like…

table_view = CDSView(source=source, filter=... )
...
table = DataTable(source=source, view=table_view)
..
def update_table(data):
    *update your filter view**
⌁   Link to post
Charlie
Charlie

Hello, thank you for your reply.

This is the last thing I tried because it seemed to me the most coherent thing to do.

But so that ‘table_view.filters’ does not update.

import pandas as pd
import numpy as np

from bokeh.models import (ColumnDataSource,  DataTable, TableColumn,
                         CDSView, IndexFilter)

from bokeh.plotting import figure, curdoc, show
from bokeh.layouts import  row




x = np.random.sample(10)
y = np.random.sample(10)
z = np.random.sample(10)

l = ['P'+str(n) for n in range(len(z))]
c = ['skyblue']*len(x)
cl= ['c1']*4 + ['c2']*3 + ['c3']*3

dataf = pd.DataFrame({'Var1': x, 'Var2': y, 'Var3': z, 'Label': l, 'color': c, 'class': cl} )



source = ColumnDataSource(data=dict(x=dataf['Var1'],
                                    y=dataf['Var2'],
                                    z=dataf['Var3'],
                                    l=dataf['Label'],
                                    c=dataf['color']
                                   ))

p1 = figure(plot_width=800, plot_height=700,
            tools="tap,pan,lasso_select,wheel_zoom,save,reset",
            toolbar_location="above",
           )


p1.circle(x="x", y="y",color='c' ,fill_alpha=0.8 ,source=source, size=10,
           selection_line_color="darkblue")


table_view = CDSView(source=source, filters=[] )

table = DataTable(source=source, view=table_view)


columns = [TableColumn(field=n,title=n) for n in ['Var1','Var2','Var3','Label']]
table = DataTable(source=source,columns=columns, width=800, height=300)

    
def update_table(data):
    table.source = ColumnDataSource(data)
    table_view.source = ColumnDataSource(data)
    table_view.filters = [IndexFilter(data.index)]
    
update_table(dataf)
    
def selection_change(attrname, old, new):
    data = dataf.copy()
    selected = source.selected.indices
    if selected:
        data = data.iloc[selected, :]
        
    update_table(data)


source.selected.on_change('indices', selection_change) 

display = row(p1,table)

curdoc().add_root(display)

Thanks again!

⌁   Link to post
crashMOGWAI
crashMOGWAI

You had some duplicate/unnecessary things messing up the flow, incorporate the changes below and it should work for you.

x = np.random.sample(10)
y = np.random.sample(10)
z = np.random.sample(10)
l = ['P'+str(n) for n in range(len(z))]
c = ['skyblue']*len(x)
cl= ['c1']*4 + ['c2']*3 + ['c3']*3

dataf = pd.DataFrame({'x': x, 'y': y, 'z': z, 'l': l, 'c': c, 'cl': cl} )

source = ColumnDataSource(dataf)

p1 = figure(plot_width=800, plot_height=700,
        tools="tap,pan,lasso_select,wheel_zoom,save,reset",
        toolbar_location="above",
       )
p1.circle(x="x", y="y",color='c' ,fill_alpha=0.8 ,source=source, size=10,
           selection_line_color="darkblue")

table_view = CDSView(source=source, filters=[])
columns = [TableColumn(field=n,title=n) for n in ['x','y','z','l']]
table = DataTable(source=source, columns=columns, view=table_view, visible=False, width=800)

def selection_change(attrname, old, new):
    table.visible = True
    table.view = CDSView(source=source, filters=[IndexFilter(source.selected.indices)])

source.selected.on_change('indices', selection_change) 

doc.add_root(column(p1,table))
⌁   Link to post
Charlie
Charlie

Hello,

Thank you very much because it worked perfectly for me.

One last thing:
would you know if there is a possibility to filter the indexes in a specific order? That is, if I define IndexFilter([4,0,1,3]) that the table above shows them in that order. This would be a very interesting functionality as it would be very easy to determine that they are sorted, but if by default they are always sorted, there is no possibility to control it.

Thank you very much for everything.

⌁   Link to post
Charlie
Charlie

Hello,

well, it’s a pity because it would be tremendously practical but it’s still beneficial for the DataTable to connect directly to any figure.

One last question, is it not possible to control the position of the headers, that is to say, to center for example the title of the columns?

Thank you very much for all your attention, it is all very pedagogical and very helpful.

⌁   Link to post
crashMOGWAI
crashMOGWAI

You’ll have to dig around in the model formatters (StringFormatter(), CellFormater(), HTMLTemplateFormatter(), etc.) to see if you can get something to touch the header.

Just for quick example you can pass a StringFormatter() to your TableColumn and center the row text with
TableColumn(field=n, title=n, formatter=StringFormatter(text_align='center'))

⌁   Link to post

End of archived discussion · Replies are disabled