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.
It's still not ideal:
Div
s instead of Title
s 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)