Consider a dummy data set of events.
df = pd.DataFrame(columns=['category', 'start','end','value','type'], data=[['A','2024-06-01','2024-06-10',0.5,'normal'],['B','2024-05-27','2024-06-16',.8,'normal'],['C','2024-06-04','2024-06-12',.3,'unusual']])
Each row defines an event with a set duration between the start and end dates, as well as a value and an event type.
The chart would show all of these events as rectangles. Time would be on the horizontal axis. The categories (A,B,C) would be on the vertical axis. The start and end dates would establish the start and end of the rectangles to show the duration of the events, which could be coloured based on their type. The height of the rectangles would be established by the ‘value’.
I have achieved this with bokeh and it works if there is only one event for each category. See my code:
import pandas as pd
import numpy as np
import seaborn as sns
from bokeh.plotting import figure, show, output_notebook, output_file
from bokeh.models import ColumnDataSource, Range1d
from bokeh.models.tools import HoverTool
output_notebook()
df = pd.DataFrame(columns=['category', 'start','end','value','type'], data=[['A','2024-06-01','2024-06-10',0.5,'normal'],['B','2024-05-27','2024-06-16',.8,'normal'],['C','2024-06-04','2024-06-12',.3,'unusual']])
c = {'normal':'green', 'unusual':'red'}
df['bottom'] = df.index + 0.5 - df['value']/2
df['top'] = df['bottom'] + df['value']
df[['start', 'end']] = df[['start', 'end']].apply(pd.to_datetime)
df['color'] = df['type'].map(c)
G = figure(title='Events', x_axis_type='datetime', width=800, height=400, y_range=df.category,
x_range=Range1d(df.start.min(), df.end.max()), tools='save')
hover = HoverTool(tooltips="Category: @category<br>\
Start: @start<br>\
End: @end")
G.add_tools(hover)
CDS = ColumnDataSource(df)
G.quad(left='start', right='end', bottom='bottom', top='top', source=CDS, color="color")
show(G)
But I have more than one event for a given category, the code breaks.
df = pd.DataFrame(columns=['category', 'start','end','value','type'], data=[['A','2024-06-01','2024-06-10',0.5,'normal'],['B','2024-05-27','2024-06-16',.8,'normal'],['C','2024-06-04','2024-06-12',.3,'unusual'],['C','2024-05-06','2024-05-20',.8,'normal']])
This is the error
ERROR:bokeh.core.validation.check:E-1019 (DUPLICATE_FACTORS): FactorRange must specify a unique list of categorical factors for an axis: duplicate factors found: 'C'
Categories with multiple events would just show multiple rectangles at the same level on the vertical axis. How can I achieve this?