Eyal S.
Eyal S.

Reputation: 1161

Bokeh skip tick labels for categorical data

I'm using Bokeh version 0.12.13. I have a mixed numerical and categorical data. I only have one categorical data on the x-axis and the rest is numerical. I converted everything to categorical data to do the plotting (might not be the easiest way to achieve my goal). Now my x-axis tick labels are way denser than I need. I would like to space them out every 10th value so the labels are 10,20,...,90,rest

This is what I tried so far:

import pandas as pd
from bokeh.io import show
from bokeh.models import ColumnDataSource
from bokeh.plotting import figure
from bokeh.models.tickers import FixedTicker

# create mock data
n = [str(i) for i in np.arange(1,100)]
n.append('rest')
t = pd.DataFrame([n,list(np.random.randint(25,size=100))]).T
t.columns = ['Number','Value']
t.loc[t['Number']==100,'Number'] = 'Rest'

source = ColumnDataSource(t)

p = figure(plot_width=800, plot_height=400, title="",
            x_range=t['Number'].tolist(),toolbar_location=None, tools="")

p.vbar(x='Number', top='Value', width=1, source=source,
       line_color="white")

#p.xaxis.ticker = FixedTicker(ticks=[i for i in range(0,100,10)])

show(p)

Ideally, I would like the grid and the x-axis labels to appear every 10th value. Any help on how to get there would be greatly appreciated.

Upvotes: 1

Views: 1355

Answers (2)

kmt
kmt

Reputation: 813

You can do this now (in Bokeh 2.2.3) using FuncTickFormatter:

# This prints out only every 10th tick label
p.axis.formatter = FuncTickFormatter(code="""
    
    if (index % 10 == 0)
    {
        return tick;
    }
    else
    {
        return "";
    }
    """)

Sometimes you might want to do this instead of using numerical axis and major_label_overrides e.g. in a heatmap to get positioning of the content rects in the right place, or if you don't have numerical data at all but still want gaps in the axis labels.

Upvotes: 1

Eyal S.
Eyal S.

Reputation: 1161

An easier way to do it is to keep the numerical data and use the xaxis.major_label_overrides. Here is the code:

import pandas as pd
from bokeh.io import show
from bokeh.models import ColumnDataSource
from bokeh.plotting import figure
from bokeh.models.tickers import FixedTicker

# create mock data
n = np.arange(1,101)
t = pd.DataFrame([n,list(np.random.randint(25,size=100))]).T
t.columns = ['Number','Value']

source = ColumnDataSource(t)

p = figure(plot_width=800, plot_height=400, title="",
            toolbar_location=None, tools="")

p.vbar(x='Number', top='Value', width=1, source=source,
       line_color="white")

p.xaxis.major_label_overrides = {100: 'Rest'}

show(p)

Upvotes: 2

Related Questions