21

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?

user3708379
  • 213
  • 1
  • 2
  • 5

3 Answers3

27

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)

enter image description here

bigreddot
  • 33,642
  • 5
  • 69
  • 122
6

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)

result of code

Matt Popovich
  • 236
  • 1
  • 2
  • 14
wordsforthewise
  • 13,746
  • 5
  • 87
  • 117
0

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)

enter image description here

GCru
  • 426
  • 6
  • 8