我想在我的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等来对其进行修复。我不要那个!正确的实现方式是什么?
谢谢