In [1]:
from bokeh.io import output_notebook, show
output_notebook()
In [2]:
# %load '../app/constants.py'
PALETTE_GREY_900 = '#212121'
PALETTE_GREY_700 = '#616161'
PALETTE_PINK_A400 = '#f50057'
COLOR_DARK_CONTRAST = 'white'
COLOR_PRIMARY = PALETTE_GREY_900
COLOR_PRIMARY_DARK = PALETTE_GREY_700
COLOR_ACCENT = PALETTE_PINK_A400
COLOR_PRIMARY_CONTRAST = COLOR_DARK_CONTRAST
COLOR_ACCENT_CONTRAST = COLOR_DARK_CONTRAST
In [3]:
# %load '../app/process_gtimelog.py'
import pandas as pd
import numpy as np
def get_raw_df():
raw = pd.read_table('timelog.txt', quotechar=' ', sep=': ', names=['timestamp', 'activity'], engine='python',)
# Set the column types
raw.timestamp = pd.to_datetime(raw.timestamp)
raw = raw.drop_duplicates()
### Build the times
raw['end'] = raw.timestamp
raw['start'] = raw['end'].shift(1)
raw['start'] = np.where(
raw['activity'] == 'start', # If the activity is start
raw['timestamp'], # Set the start to timestamp
raw['start'], # Else leave it as start
)
raw['delta'] = raw.end - raw.start
return raw
def keep_top_level_cats_only(gt_df):
"""
Takes a gtimelog DataFrame, and removes the non-work categories, and
boils the other categories down to their high-level category.
"""
gt_df = gt_df[~gt_df.activity.str.contains(r'\*\*\*')]
# Boil down the categories to the main work categories
gt_df.activity = gt_df.activity.str.split(r' ').str[0]
return gt_df
In [4]:
raw = get_raw_df()
raw.tail()
Out[4]:
In [5]:
import datetime
In [6]:
# today = datetime.date.today()
today = datetime.date(2015, 7, 6)
yesterday = datetime.date(2015, 7, 3)
In [7]:
just_today = raw[(raw.timestamp.dt.date == today) | (raw.timestamp.dt.date == yesterday)]
just_today = just_today[just_today.activity != 'start']
just_today['human'] = just_today.delta.dt.seconds / (60 * 60)
just_today.head()
Out[7]:
In [8]:
group_sum = just_today[['activity', 'timestamp', 'human']].groupby(['activity', just_today.timestamp.dt.date]).sum()
group_sum = group_sum.unstack('activity')
group_sum
Out[8]:
In [9]:
print(group_sum.columns)
levels = group_sum.columns.levels
labels = group_sum.columns.labels
group_sum.columns = levels[1][labels[1]]
print(group_sum.columns)
In [10]:
group_sum.sort_index(inplace=True)
group_sum.fillna(0, inplace=True)
group_sum
Out[10]:
In [11]:
group_sum.columns
Out[11]:
In [12]:
from bokeh.charts import Bar
from bokeh import palettes
palette = getattr(palettes, 'Spectral%s' % len(group_sum.columns))
show(Bar(group_sum, palette=palette, legend=True))
In [13]:
bar = Bar(
group_sum, tools='hover', legend=True,
palette=palette,
width=600, height=300,
)
# Get chart items
from bokeh.models import Legend, LinearAxis, CategoricalAxis, GlyphRenderer, HoverTool
legend = bar.select({'type': Legend})
hover = bar.select({'type': HoverTool})
glyphs = bar.select({'type': GlyphRenderer})
xaxis = bar.select({'type': CategoricalAxis})
yaxis = bar.select({'type': LinearAxis})
In [14]:
# Format chart properties
bar.toolbar_location=None
bar.background_fill = COLOR_PRIMARY
bar.border_fill = COLOR_PRIMARY
bar.outline_line_color = None
bar.min_border_top = 0
In [15]:
legend.label_text_color = COLOR_PRIMARY_CONTRAST
legend.border_line_color = COLOR_PRIMARY_CONTRAST
hover.tooltips = [('hours', '$y')]
hover.point_policy = 'follow_mouse'
for g in glyphs:
g.glyph.fill_alpha = 1
g.glyph.line_color = None
In [16]:
from bokeh.models import DatetimeTickFormatter
# Set xaxis properties
xaxis.major_label_text_color = COLOR_PRIMARY_CONTRAST
xaxis.major_label_orientation = 0
xaxis.major_label_standoff = 15
xaxis.formatter = DatetimeTickFormatter(
formats={
'years': ["%a %d %b"],
}
)
xaxis.major_tick_out = None
xaxis.major_tick_in = None
xaxis.axis_line_color = None
In [17]:
# Set yaxis properties
yaxis.major_label_text_color = COLOR_PRIMARY_CONTRAST
yaxis.major_tick_out = None
yaxis.major_tick_in = None
yaxis.axis_line_color = None
In [18]:
show(bar)
In [ ]:
In [ ]:
In [ ]:
In [ ]:
In [ ]: