Is there a way to use text based X values with Bokeh?

Viewed 298

I am trying to plot a simple chart with Bokeh but it fails to display anything when the x values are text based:

x=['-', 'AF', 'AS', 'EU', 'NA', 'OC', 'SA']
y=[8, 7621750, 33785311, 31486697, 38006434, 7312002, 7284879]
p = figure(plot_width=480, plot_height=300,title='test')
p.vbar(x=x, width=0.5, bottom=0, top=y, color="navy", alpha=0.5)
p.toolbar.logo = None
p.toolbar_location = None
v = gridplot([[p]])
show(v)

enter image description here

I am wondering if this is a bug. Version: 0.13.0

After applying the suggested fix it works:

for i in range(4):
    ind=i+offset
    rez[ind].sort(key=lambda tup: tup[0])
    x = [x[0] for x in rez[ind]]
    y = [x[1] for x in rez[ind]]
    if type(x[0]) == str:
        charts[i] = figure(
            plot_width=480, 
            plot_height=300,
            title=columns_being_investigated[ind],
            x_range=x)
    else:
        charts[i] = figure(
            plot_width=480, 
            plot_height=300,
            title=columns_being_investigated[ind])
    charts[i].vbar(x=x, width=0.5, bottom=0, top=y, color="navy", alpha=0.5)
    charts[i].toolbar.logo = None
    charts[i].toolbar_location = None

p = gridplot([[charts[0], charts[1]], [charts[2], charts[3]]])
show(p)
1 Answers

When using categorical (i.e. string) coordinates, you have to inform Bokeh what the order of the categorical factors should be in. It's arbitrary, and up to you, there is no order Bokeh could pick by default. For simple non-nested categories this is most easily done by passing a list to figure as the x_range argument.

All of this information is in the docs: Handling Categorical Data

Your code updated:

from bokeh.plotting import figure, show

x=['-', 'AF', 'AS', 'EU', 'NA', 'OC', 'SA']
y=[8, 7621750, 33785311, 31486697, 38006434, 7312002, 7284879]
p = figure(plot_width=480, plot_height=300,title='test', 

           # you were missing this:
           x_range=['-', 'AF', 'AS', 'EU', 'NA', 'OC', 'SA'])

p.vbar(x=x, width=0.5, bottom=0, top=y, color="navy", alpha=0.5)
p.toolbar.logo = None
p.toolbar_location = None
show(p)

That results in this output:

enter image description here

Related