python - Add custom tooltips on pie chart in Bokeh and display correctly -


i have encountered problems when trying add custom value in hovertool.tooltips using bokeh.charts.donut.

i trying add percentage tag in hovertool.tooltips. sure common practice have percentage values shown in pie charts along absolute values increases readability.

as bokeh.charts.donut high level chart api, can't seem make custom hovertool.tooltips work shown in doc.

from bokeh.plotting import output_notebook bokeh.charts import show,donut bokeh.models import hovertool import pandas pd output_notebook()  d = {'posa': ['us','it','fr','es','de','gb','ca','be','au','nl','no','se','dk'],  'values': [4464, 989, 875, 824, 773, 733, 598, 307, 140, 132, 118, 112, 65]} df = pd.dataframe(d) df['percentage'] = df['values']/df['values'].sum()  pie_chart = donut(df,title='distribution of unmatched posa',label='posa',values='values',plot_width=700,plot_height=700,) hover = pie_chart.select(dict(type=hovertool)) hover.tooltips = [('percentage', '@percentage'),('value','@values')] show(pie_chart) 

the code above yields graph percentage: ??? in tooltip.

enter image description here

i fix percentage tag , display correctly.

any appreciated!

thanks.

i took matters hands , wrote builderclass similar high level chart apis in bokeh.charts.

class , function:

from numpy import pi random import shuffle math import sin,cos bokeh.plotting import columndatasource,output_notebook,figure bokeh.charts import show,donut bokeh.models import hovertool,text bokeh import palettes import pandas pd  output_notebook()  class custompiebuilder:     green ="#50ee70"     red = "#ff7070"     x_range = 1.1     y_range = 1.1      def __init__(self,df,label_name,column_name,tools='hover',tooltips=none,                  reverse_color=false,colors=none,random_color_order=false,                  plot_width=400,plot_height=400,title='untitled',*args,**kwargs):         p = self.setup_figure(tools,plot_width,plot_height,title)         df = self.add_columns_for_pie_chart(df,column_name,colors,reverse_color,random_color_order)         self.df = df         self.plot_pie(p,df,label_name,*args,**kwargs)         if tooltips:             self.set_hover_tooltip(p,tooltips)          self.add_text_label_on_pie(p,df,label_name)         self.plot = p      def setup_figure(self,tools,plot_width,plot_height,title):         p = figure(             x_range=(-self.x_range, self.x_range),             y_range=(-self.y_range, self.y_range),             tools=tools,             plot_width=plot_width,             plot_height=plot_height,             title=title,         )         p.axis.visible = false         p.xgrid.grid_line_color = none         p.ygrid.grid_line_color = none         return p      @staticmethod     def plot_pie(p,df,label_name,*args,**kwargs):         key, _df in df.groupby(label_name):             source = columndatasource(_df.to_dict(orient='list'))             p.annular_wedge(                 x=0,                 y=0,                 inner_radius=0,                 outer_radius=1,                 start_angle='starts',                 end_angle='ends',                 color='colors',                 source=source,                 legend=key,                 *args,**kwargs)      @staticmethod     def set_hover_tooltip(p,tooltips):         hover = p.select({'type':hovertool})         hover.tooltips = tooltips      @staticmethod     def add_columns_for_pie_chart(df,column_name,colors=none,reverse_color=false,random_color_order=false):         r = 0.7         df = df.copy()         column_sum = df[column_name].sum()         df['percentage'] = (df[column_name]/column_sum)         percentages = [0]  + df['percentage'].cumsum().tolist()         df['starts'] = [p * 2 * pi p in percentages[:-1]]         df['ends'] = [p * 2 * pi p in percentages[1:]]          df['middle'] = (df['starts'] + df['ends'])/2         df['text_x'] = df['middle'].apply(cos)*r         df['text_y'] =df['middle'].apply(sin)*r          df['text_angle'] = 0.0          if colors:             df['colors'] = colors         else:             if 'colors' not in df:                 reverse_color = -1 if reverse_color else 1                 colors = palettes.viridis(len(df))[::reverse_color]                 if random_color_order:                     shuffle(colors)                 df['colors'] = colors         return df      @staticmethod     def add_text_label_on_pie(p,df,label_name):         source=columndatasource(df.to_dict(orient='list'))         txt = text(x="text_x", y="text_y", text=label_name, angle="text_angle",                text_align="center", text_baseline="middle",                text_font_size='10pt',)         p.add_glyph(source,txt)  def build_plot(df,label_name,column_name,tools='hover',tooltips=none,                  reverse_color=false,colors=none,random_color_order=false,                  plot_width=400,plot_height=400,title='untitled',*args,**kwargs):      custompie = custompiebuilder(df,label_name,column_name,tools,tooltips,                  reverse_color,colors,random_color_order,                  plot_width,plot_height,title,*args,**kwargs)      return custompie.plot 

code:

d = {'posa': ['us','it','fr','es','de','gb','ca','be','au','nl','no','se','dk'],  'values': [4464, 989, 875, 824, 773, 733, 598, 307, 140, 132, 118, 112, 65]} df = pd.dataframe(d)  p = build_plot(     df,     'posa',     'values',     tooltips=[('percentage', '@percentage{0.00%}'), ('posa', '@posa'), ('count','@values')],     title='testing',     reverse_color=true,     random_color_order=true,     plot_height=700,     plot_width=700)  show(p) 

graph: enter image description here


Comments

Popular posts from this blog

node.js - Node js - Trying to send POST request, but it is not loading javascript content -

javascript - Replicate keyboard event with html button -

javascript - Web audio api 5.1 surround example not working in firefox -