It is not possible to use a CategoricalAxis
with a FactorRange
and set the x_range
because start
and end
are readonly properties.
But there are workarounds, two are listed below.
using CustomJSTickFormatter
In the bokeh version 3.0.0 a CustomJSTickFormatter
was added. With this it is possible to use a normal LinearRange
and format the ticks. With this approach you can set x_range
as you like it.
from bokeh.models import CustomJSTickFormatter, Range1d
from bokeh.plotting import figure, show, output_notebook
output_notebook()
fruits = ["Apples", "Pears", "Nectarines", "Plums", "Grapes", "Strawberries"]
x = list(range(len(fruits)))
y = [5, 3, 4, 2, 4, 6]
p = figure(height=250, title="Fruit Counts")
p.x_range = Range1d(-0.5, 3.5, bounds=(-0.5, 4.5))
p.y_range = Range1d(0, 7)
p.vbar(x=x, top=y, width=0.9)
p.xgrid.grid_line_color = None
p.xaxis.formatter = CustomJSTickFormatter(
code="""
var new_tick= tick.toFixed(2)
const fruits = ["Apples", "Pears", "Nectarines", "Plums", "Grapes", "Strawberries"]
const range = [...Array(fruits.length).keys()]
if( tick in range )
new_tick= fruits[tick]
else
new_tick= ''
return new_tick
"""
)
p.xaxis.minor_tick_line_color = None
p.xaxis.axis_label_text_color = None
show(p)
using FixedTicker
and major_label_overrides
With a FixedTicker
you can set the ticks to you wanted positions and major_label_overrides
offers you the opportunity to set the label text very precise. This is also available before the 3.0.0 release.
from bokeh.models import FixedTicker, Range1d
from bokeh.plotting import figure, show, output_notebook
output_notebook()
fruits = ["Apples", "Pears", "Nectarines", "Plums", "Grapes", "Strawberries"]
x = list(range(len(fruits)))
y = [5, 3, 4, 2, 4, 6]
p = figure(height=250, title="Fruit Counts")
p.x_range = Range1d(-0.5, 3.5, bounds=(-0.5, 4.5))
p.y_range = Range1d(0, 7)
p.vbar(x=x, top=y, width=0.9)
p.xgrid.grid_line_color = None
p.xaxis.ticker = FixedTicker(
desired_num_ticks=len(fruits),
num_minor_ticks = 0,
ticks=x
)
p.xaxis.major_label_overrides = {i: label for i, label in zip(x, fruits)}
show(p)
The visual results should be the same and the inital view looks like below:
