Histogram with two y-axis 'count' and 'percentage' in bokeh?

89 Views Asked by At

I am new to bokeh. What is the clean way of creating a histogram of the data in bokeh, with two y-axis one is "count" and one is "percentage"? I used quad to create the histogram with "count" axis label, then added the second axis using the extra_y_ranges and the add_layout. Unfortunately the y-axis are not always aligned. I'am sure there is a better way to do this. Also how can I rotate the right y_axis label? I want that to have thee same orientation as the left y_axis. I eventually like to also overlay the pdf of the distribution as well.

Appreciate your help.

Here is the plots I created with 'quad' and extra_y_ranges and I get this and don't like the orientation of the 'Percentage'.enter image description here

1

There are 1 best solutions below

0
mosc9575 On

My advise is

  1. set a Range1d from bokeh.models to both of your y-axis based on your data
  2. draw the quad twice, one the second y-axis without any color
  3. use axis_label_orientation to set the orientation of the labels

Here is a minimal example:

Here is a very minimal data set stored in a pandas DataFrame

import pandas as pd
df = pd.DataFrame({'data':[12,1,2,11,22,3,4]})
df['percent'] = df['data'] / df["data"].sum()
df['left'] = df.index - 0.4
df['right'] = df.index + 0.4

The bokeh section looks like below.

from bokeh.models import ColumnDataSource, LinearAxis, Range1d
from bokeh.plotting import figure, show, output_notebook
output_notebook()

source= ColumnDataSource(df)

# figure
p = figure(width=700, height=300)

# default axis
p.quad(top='data', bottom=0, left='left', right='right', source=source)
p.yaxis.axis_label = "count"
p.yaxis.axis_label_orientation = 'horizontal'
p.y_range = Range1d(0, df['data'].max() * 1.05)

# second axis
p.extra_y_ranges['percent'] = Range1d(0, df['percent'].max() * 1.05)
red_circles = p.quad(
    top='data',
    bottom=0,
    left='left',
    right='right',
    source=source,
    color=None,
    y_range_name="percent"
)

ax2 = LinearAxis(
    axis_label="percent",
    y_range_name="percent",
    axis_label_orientation = 'horizontal'
)
p.add_layout(ax2, 'right')

# output
show(p)

one data set with two y axis