Reputation: 103
Apologies for having a long post. I am working on a visualisation that represents weekly inventory values of different locations. I am able to hide some locations from the graph by clicking the legend, but the y axis don't update itself. That is why I tried to implement CheckBoxGroup to filter the graph's items. However, I can draw the graph, but whenever I deselect some items in CheckBoxGroup, the graph is not updating itself. You can find image of the output below. Any help would be useful.
P.S: In order to reproduce the output processing the data codes must be run at first then graph codes.
Thank you, E
Output: Output of the code
Data : link
Processing the data:
import pandas as pd
import numpy as np
dataset_inventory = pd.read_excel('weekly_inventory_data.xls')
df = dataset_inventory.copy()
df = df.fillna(0)
df = df.replace('-',0)
resource = "çÇğĞıİöÖşŞüÜ"
target = "cCgGiIoOsSuU"
translate = str.maketrans(resource,target)
df['Location']= df['Location'].str.translate(translate)
df.columns = [x.lower() if type(x)==str else x for x in df.columns]
df['location'] = [x.lower() for x in df['location']]
df1 = df.copy()
df2 =df.copy()
for column in df2:
if type(column) == int:
df2[column] = [1 if x>0 else 0 for x in df2[column]]
else:
pass
def table(df,info):
pivot = df.groupby('location').sum().T
pivot.columns.names = ['']
pivot['total'] = pivot.sum(axis=1)
pivot.reset_index(level=0, inplace=True)
pivot.insert(loc=0, column='year', value=np.where(pivot['index'].apply(lambda x: x > 16), 2015, 2016))
pivot.insert(loc=2, column='year_week', value=pivot['year'].astype(str) +'_'+ pivot['index'].astype(str))
pivot.reset_index(inplace=True)
pivot.rename(columns={'level_0' :'observation','index':'week'}, inplace=True)
pivot['year_week'] = pd.Categorical(pivot.year_week, ordered=True)
pivot['observation'] = [x+1 for x in pivot['observation']]
pivot.rename(columns={'cayirova' :'cayirova_'+info, 'orhanli' :'orhanli_'+info,
'fason' :'fason_'+info, 'samandira' :'samandira_'+info,
'gebze' :'gebze_'+info, 'sultanbeyli' :'sultanbeyli_'+info,
'yenidogan' :'yenidogan_'+info, 'total' :'total_'+info
}, inplace=True)
return pivot
input1='qty'
input2='wh'
df1 = table(df1,input1)
df2 = table(df2,input2)
pivot = pd.concat([df1, df2.drop(['observation','year','week','year_week'],axis =1)], axis=1, sort=False)
cols_to_order = ['observation', 'year','week','year_week','total_'+input1,'total_'+input2]
new_columns = cols_to_order + (sorted(pivot.columns.drop(cols_to_order).tolist()))
inventory_pivot = pivot[new_columns]
inventory_pivot = inventory_pivot.set_index('observation')
inventory_pivot.insert(loc=0, column='date', value=pd.to_datetime(inventory_pivot.year.astype(str), format='%Y') + \
pd.to_timedelta(inventory_pivot.week.mul(7).astype(str) + ' days'))
Graphing:
import pandas as pd
from bokeh.plotting import figure, output_file, show
import pandas as pd
import numpy as np
from bokeh.io import output_file, output_notebook, push_notebook
from bokeh.plotting import figure, show
from bokeh.models import ColumnDataSource
from bokeh.layouts import row, column, gridplot
from bokeh.models.widgets import Tabs, Panel
from bokeh.models import HoverTool
from bokeh.models import ColumnDataSource
from bokeh.models import NumeralTickFormatter
from bokeh.models import DatetimeTickFormatter
from math import pi
from bokeh.models import Legend
from bokeh.layouts import column, row
from bokeh.models import Column
from bokeh.application.handlers import FunctionHandler
from bokeh.application import Application
from bokeh.models.widgets import CheckboxGroup
inventory = ColumnDataSource(inventory_pivot)
def modify(doc):
def update(attr, old, new):
items_to_plot = [item_selection.labels[i] for i in
item_selection.active]
def graph(items):
fig = figure(plot_width=850, plot_height=500, x_axis_type="datetime", toolbar_location=None)
fig.title.text = 'Click on legend entries to hide the corresponding lines'
colors = ['blue','green','purple','brown','black','orange','red','yellow']
legend_it = []
for idx,item in enumerate(items):
graph = fig.line(x='date', y =item+'_'+input1,
source=inventory,
line_width=3,
color = colors[idx])
legend_it.append((item, [graph]))
legend = Legend(items=legend_it, location=(10,130))
legend.click_policy="hide"
fig.add_layout(legend, 'right')
fig.legend.border_line_width = 1
fig.legend.border_line_color = "navy"
fig.legend.border_line_alpha = 0.5
fig.ygrid.visible = False
fig.xgrid.visible = False
fig.yaxis.formatter=NumeralTickFormatter(format=",")
fig.xaxis.major_label_orientation = pi/3
fig.y_range.start = 0
fig.xaxis.formatter=DatetimeTickFormatter(
months=["%B %Y"],
years=["%B %Y"], )
tooltips = [
('YEAR','@year'),
('WEEK','@week'),
('QUANTITY','$y{,}')
]
fig.add_tools(HoverTool(tooltips=tooltips))
return fig
items_list = ['total','yenidogan','cayirova','sultanbeyli','samandira','orhanli','gebze','fason']
item_selection = CheckboxGroup(labels=items_list,
active = [0, 1, 2, 3, 4, 5, 6, 7], width =100)
item_selection.on_change('active', update)
controls = Column(item_selection)
initial_list = [item_selection.labels[i] for i in item_selection.active]
fig = graph(initial_list)
layout = row(controls, fig)
doc.add_root(layout)
output_notebook()
handler = FunctionHandler(modify)
app = Application(handler)
show(app)
Upvotes: 1
Views: 143
Reputation: 10652
You don't need the checkbox group. Just add fig.y_range.only_visible = True
somewhere.
Upvotes: 1