OiO.lk Community platform!

Oio.lk is an excellent forum for developers, providing a wide range of resources, discussions, and support for those in the developer community. Join oio.lk today to connect with like-minded professionals, share insights, and stay updated on the latest trends and technologies in the development field.
  You need to log in or register to access the solved answers to this problem.
  • You have reached the maximum number of guest views allowed
  • Please register below to remove this limitation

Plot events as rectangles with start-end dates along x axis (rectangle width) and magnitude along y axis (rectangle height)

  • Thread starter Thread starter ric
  • Start date Start date
R

ric

Guest
Consider a dummy data set of events

Code:
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:

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.

Code:
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

Code:
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?
<p>Consider a dummy data set of events</p>
<pre><code>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']])
</code></pre>
<p>Each row defines an event with a set duration between the start and end dates, as well as a value and an event type.</p>
<p>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'.</p>
<p>I have achieved this with bokeh and it works if there is only one event for each category. See my code:</p>
<pre><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)
</code></pre>
<p>But I have more than one event for a given category, the code breaks.</p>
<pre><code>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']])
</code></pre>
<p>This is the error</p>
<pre><code>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'
</code></pre>
<p>Categories with multiple events would just show multiple rectangles at the same level on the vertical axis. How can I achieve this?</p>
 

Latest posts

B
Replies
0
Views
1
Blundering Ecologist
B
Top