Reputation: 263
I understand how you specify specific ticks to show in Bokeh, but my question is if there is a way to assign a specific label to show versus the position. So for example
plot.xaxis[0].ticker=FixedTicker(ticks=[0,1])
will only show the x-axis labels at 0 and 1, but what if instead of showing 0 and 1 I wanted to show Apple and Orange. Something like
plot.xaxis[0].ticker=FixedTicker(ticks=[0,1], labels=['Apple', 'Orange'])
A histogram won't work for the data I am plotting. Is there anyway to use custom labels in Bokeh like this?
Upvotes: 26
Views: 27159
Reputation: 1467
Label for x ticks which do not fall on the multiple(s) of ten may not be visible. It might be as a result of data points not been accurate or manipulated in a certain way. If it happens to you,
Hack on bokeh 3.1.1 for that is to use padding to spread the label for ticks at multiples of 10. My figure has x range of 50 and y range of 25 with min_height of 800 and min_width of 1600.
See below (Note the spaces given deliberately in label text) -
label_dict = { 0: "g (1-7)", 1: "", 2: "", 3: "", 4: "", 5: "", 6: "", 7: "", 8: "", 9: "", 10: "O (8-13)", 11: "", 12: "", 13: "", 14: "", 15: "", 16: "", 17: "", 18: "", 19: "", 20: "E (14-18) I (19-24)", 21: "", 22: "", 23: "", 24: "", 25: "", 26: "", 27: "", 28: "", 29: "", 30: "C (25-35) ", 31: "", 32: "", 33: "", 34: "", 35: "", 36: "", 37: "", 38: "", 39: "", 40: "λ(36) k(37) A / L (38-40)", 41: "", 42: "", 43: "", 44: "", 45: "", 46: "", 47: "", 48: "", 49: ""}
fig.xaxis.major_label_overrides = label_dict
Upvotes: 2
Reputation: 15777
EDIT: Updated for Bokeh 0.12.5
but also see simpler method in the other answer.
This worked for me:
import pandas as pd
from bokeh.charts import Bar, output_file, show
from bokeh.models import TickFormatter
from bokeh.core.properties import Dict, Int, String
class FixedTickFormatter(TickFormatter):
"""
Class used to allow custom axis tick labels on a bokeh chart
Extends bokeh.model.formatters.TickFormatte
"""
JS_CODE = """
import {Model} from "model"
import * as p from "core/properties"
export class FixedTickFormatter extends Model
type: 'FixedTickFormatter'
doFormat: (ticks) ->
labels = @get("labels")
return (labels[tick] ? "" for tick in ticks)
@define {
labels: [ p.Any ]
}
"""
labels = Dict(Int, String, help="""
A mapping of integer ticks values to their labels.
""")
__implementation__ = JS_CODE
skills_list = ['cheese making', 'squanching', 'leaving harsh criticisms']
pct_counts = [25, 40, 1]
df = pd.DataFrame({'skill':skills_list, 'pct jobs with skill':pct_counts})
p = Bar(df, 'index', values='pct jobs with skill', title="Top skills for ___ jobs", legend=False)
label_dict = {}
for i, s in enumerate(skills_list):
label_dict[i] = s
p.xaxis[0].formatter = FixedTickFormatter(labels=label_dict)
output_file("bar.html")
show(p)
Upvotes: 7
Reputation: 516
This can be dealt with as categorical data, see bokeh documentation.
from bokeh.plotting import figure, show
categories = ['A', 'B','C' ]
p = figure(x_range=categories)
p.circle(x=categories, y=[4, 6, 5], size=20)
show(p)
Upvotes: 2
Reputation: 34568
Fixed ticks can just be passed directly as the "ticker" value, and major label overrides can be provided to explicitly supply custom labels for specific values:
from bokeh.plotting import figure, output_file, show
p = figure()
p.circle(x=[1,2,3], y=[4,6,5], size=20)
p.xaxis.ticker = [1, 2, 3]
p.xaxis.major_label_overrides = {1: 'A', 2: 'B', 3: 'C'}
output_file("test.html")
show(p)
Upvotes: 31