Varun M. Chaturmutha
Varun M. Chaturmutha

Reputation: 33

Bokeh labels don't render if x axis values are categorical after version update

I am new to Bokeh (using v2.2.1) and looking for solution to label each data point. Replicating the examples shown in documents, I could not find solutions with X axis being string,

import pandas as pd
from bokeh.models import LabelSet, ColumnDataSource
from bokeh.plotting import figure, show

output_file("weekday_val.html")

vals = pd.DataFrame({'weekday': ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'],
                     'Sales': [15, 25, 36, 17, 4]})

ds = ColumnDataSource(vals)

p = figure(x_range=vals['weekday'])
p.vbar(x='weekday', width=0.75, top='Sales', source=ds)

labels = LabelSet(x='weekday', y='Sales', text='Sales', source=ds, 
                  level='glyph',
                  x_offset=5, 
                  y_offset=5, 
                  render_mode='canvas')
p.add_layout(labels)

show(p)

It's not giving any error but it is failing to print the labels on top of the vertical bars as I was expecting. This error occurred only after I upgraded Bokeh from v1.2.0 to v2.1.1.

Does LabelSet only take numerical values for the x-axis? Is there a workaround to use this for x-axis with strings?

Upvotes: 3

Views: 1188

Answers (1)

gherka
gherka

Reputation: 1446

As Eugene Pakhomov says in the comments, there is an issue in 2.2.1 regarding categorical coordinates and labels. It's due to be fixed in 2.3, but in the meantime, you can replace your categorical values with their indices and the annotations will render as expected.

import pandas as pd
from bokeh.models import LabelSet, ColumnDataSource, Range1d
from bokeh.plotting import output_notebook, figure, show

output_notebook()

vals = pd.DataFrame({'weekday': ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'],
                     'Sales': [15, 25, 36, 17, 4],
                     'index' : range(5)}
                   )

ds = ColumnDataSource(vals)

# extend the y-range a bit more to give space to top label
p = figure(y_range=Range1d(0, 42), x_range=vals['weekday'], height=300)
p.vbar(x='weekday', width=0.75, top='Sales', source=ds)

labels = LabelSet(x='index', y='Sales', text='Sales', source=ds, 
                  level='glyph',
                  x_offset=5, 
                  y_offset=5, 
                  render_mode='canvas')

p.add_layout(labels)

show(p)

enter image description here

Upvotes: 3

Related Questions