为散景饼图添加百分比标签

时间:2019-01-22 19:09:55

标签: python bokeh pie-chart

我想在我的Bokeh甜甜圈图中添加百分比作为标签。我完成了!有点数学!但我认为必须有一个更好的内置解决方案。我看到了一些解决方案,但它们来自旧版本的Bokeh,因此不适用于我。我正在分享我的代码和结果:

from math import pi
from bokeh.palettes import Category10
from bokeh.models.sources import ColumnDataSource
from bokeh.plotting import figure
from bokeh.transform import cumsum 
from bokeh.models import Legend, HoverTool, LabelSet
from bokeh.io import output_notebook, show, push_notebook
import numpy as np

output_notebook()

value = [10,20,30,40]*5

data = {'name': ["A", "B","C","D"]*5,                               
        'value': value,                     
        'angle': [v/sum(value)*2*pi for v in value],
        'cumulative_angle':[(sum(value[0:i+1])- (item/2))/sum(value)*2*pi for i,item in enumerate(value)],
        'percentage': [d/sum(value)*100 for d in value],
        'color': Category10[5][1:]*5}      

data['label'] = ["{:.0f}%".format(p) for p in data['percentage']]
data['cos'] = np.cos(data['cumulative_angle'])*0.3
data['sin'] = np.sin(data['cumulative_angle'])*0.3

source = ColumnDataSource(data=data)


TOOLTIPS = [ 
  ("Value", "@value"),
  ("Percentage", "@percentage{0.2f}%")
] 


p = figure(plot_height=600,plot_width=600,x_range=(-1,1), y_range=(-1,1), tools='hover',
           tooltips=TOOLTIPS, title="My Donut Chart", toolbar_location=None)


r = p.annular_wedge(x=0, y=0, inner_radius=0.2, outer_radius=0.4,
        start_angle=cumsum('angle', include_zero=True), end_angle=cumsum('angle'),
        line_color="white", fill_color='color', fill_alpha=1, source=source)


legend = Legend(items=[LegendItem(label=dict(field="name"), renderers=[r])], location=(0, 80)) 
p.add_layout(legend, 'right') 


labels = LabelSet(x='cos', y='sin', text="label", y_offset=0,
          text_font_size="6pt", text_color="black",
          source=source, text_align='center')

p.add_layout(labels)


p.axis.axis_label=None
p.axis.visible=False
p.grid.grid_line_color = None
p.outline_line_color = None


show(p)

the current Pie chart with percentages

尽管我认为这在数学上是正确的,但它并不总是有效!这可能是因为Bokeh的内部尺寸。例如,如果您更改宽度和高度,则百分比可能会分散,您需要设置y_offset等来对其进行修复。我不要那个!正确的实现方式是什么?

谢谢

0 个答案:

没有答案