In bokeh, we could create categorical coordinates plot. https://docs.bokeh.org/en/latest/docs/user_guide/categorical.html
Can I plot something like ggplot's facet_grid? Having two level X axis in different location. (top and bottom) Thanks.

In bokeh, we could create categorical coordinates plot. https://docs.bokeh.org/en/latest/docs/user_guide/categorical.html
Can I plot something like ggplot's facet_grid? Having two level X axis in different location. (top and bottom) Thanks.

I am not sure bokeh has anything straight out of the box to do this. You would probably have to create the plot that you want, then run it through some sort of for loop and then use a layout.
It's still not ideal:
Divs instead of Titles with manual positioning)from random import random, randint
from bokeh.io import show
from bokeh.models import Div, Title
from bokeh.plotting import figure
from bokeh import layouts
major_x = ['Fri', 'Sat', 'Sun', 'Thur']
major_y = ['Female', 'Male']
minor_x = (0, 50)
minor_y = (0, 1)
height = 300
width = 300
def generate_datum(start, end):
return random() * (end - start) + start
def generate_data():
n = randint(10, 100)
return dict(x=[generate_datum(*minor_x) for _ in range(n)],
y=[generate_datum(*minor_y) for _ in range(n)])
full_data = {(x, y): generate_data() for x in major_x for y in major_y}
def pad_range(start, end):
d = (end - start) * 0.1
return start - d, end + d
def add_title(p, text, position):
t = Title(text=text, align='center')
p.add_layout(t, position)
column = []
for y in major_y:
row = []
for x in major_x:
p = figure(x_range=pad_range(*minor_x), y_range=pad_range(*minor_y),
toolbar_location=None, tools='hover', width=width, height=height)
p.xaxis.visible = (y == major_y[-1])
p.yaxis.visible = (x == major_x[0])
data = full_data[(x, y)]
p.circle(x=data['x'], y=data['y'])
if y == major_y[0]:
add_title(p, x, 'above')
if x == major_x[-1]:
add_title(p, y, 'right')
row.append(p)
column.append(layouts.row(row))
major_y_label = f'''
<div style="display: flex; align-items: center; height: {height * len(major_y)}px;">
<div style="writing-mode: tb-rl; transform: rotate(-180deg); font-size: 1.5em;">
tip/total_bill
</div>
</div>
'''
major_x_label = f'''
<div style="display: flex; justify-content: center; width: {width * len(major_x)}px;">
<div style="font-size: 1.5em;">
total_bill
</div>
</div>
'''
full_plot = layouts.grid([[Div(text=major_y_label), layouts.column(column)],
[None, Div(text=major_x_label)]])
show(full_plot)