Search code examples
pythonpandasdatatablebokeh

How do you replace the index column in Bokeh DataTable?


I created a DataTable in Bokeh, but it doesn't show the index column:

enter image description here

I expected to have the "Index" column in left:

enter image description here

This is my code:

evolution_data = treatcriteria_daily_data_table.groupby(['startdate_dayweek','startdate_weekyear'],as_index = False).sum().pivot('startdate_dayweek','startdate_weekyear').fillna(0)

evolution_data = evolution_data.droplevel(0,1)

evolution_data.loc['Total'] = evolution_data.sum()
evolution_data['Index'] = ['Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi', 'Dimanche', 'Total']
evolution_data.set_index('Index', inplace=True, drop=True)

# remove the last week if there is not all the data 
evolution_data = evolution_data.loc[:, ~(evolution_data == 0.).any()]

evolution_two_last_weeks = []

nb_cols = len(evolution_data.columns)
diff_cpu_2_last_weeks = evolution_data.iat[7, nb_cols - 1] - evolution_data.iat[7, nb_cols - 2]

for i in range(0,7):
    daily_evolution = (data_2_weeks_before_the_last.iat[1,i] - data_2_weeks_before_the_last.iat[0,i]) / diff_cpu_2_last_weeks
    evolution_two_last_weeks.append(daily_evolution)

variation_of_total = (data_2_weeks_before_the_last.iat[1,7] - data_2_weeks_before_the_last.iat[0,7]) / data_2_weeks_before_the_last.iat[0,7]

daily_variations_dict = {"Lundi": evolution_two_last_weeks[0],
                            "Mardi": evolution_two_last_weeks[1],
                            "Mercredi": evolution_two_last_weeks[2],
                            "Jeudi": evolution_two_last_weeks[3],
                            "Vendredi": evolution_two_last_weeks[4],
                            "Samedi": evolution_two_last_weeks[5],
                            "Dimanche": evolution_two_last_weeks[6],
                            "Total": variation_of_total}


# remove decimals in the table
cols = evolution_data.columns
evolution_data[cols] = evolution_data[cols].applymap(np.int64)

evolution_data['% évolution des 2 dernières semaines'] = evolution_data.index.map(mapper=(lambda x: daily_variations_dict[x]))

evolution_data['% évolution des 2 dernières semaines'] = pd.Series(["{0:.2f}%".format(val*100) for val in evolution_data['% évolution des 2 dernières semaines']], index = evolution_data.index)


print(evolution_data)

Columns = [TableColumn(field=Ci, title=Ci) for Ci in evolution_data.columns] # bokeh columns
data_table = DataTable(columns=Columns, source=ColumnDataSource(evolution_data)) # bokeh table

show(data_table)

How to show the index column (with day names) and not the row number? Thank you.


Solution

  • As already said in comments Bokeh doesn't support altering the first column which is always fixed and indicates the 0-based row number. However, under the hood, Bokeh uses the SlickGrid which does allows this functionality, but this solution is too complicated as you would need to find the reference to the SlickGrid object first in the Bokeh model and then replace the first column in JavaScript right after the page load.

    Much more simple way is as suggested to hide the first column using index_position = None so you could do data_table = DataTable(... , index_position = None) and then add the Index data from your DataFrame as first one to the table's columns. The reason that it is not there now is that the df.columns doesn't include the index column that you need. So try:

    cols.insert(0, 'Index')
    data_table = DataTable(columns=Columns, 
                           source=ColumnDataSource(evolution_data), 
                           index_position = None) # add this line