向散景饼图楔形添加标签 [英] Adding labels to bokeh pie chart wedge

查看:84
本文介绍了向散景饼图楔形添加标签的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是散景的新手,想使用散景图渲染饼图.

I am new to bokeh, and want to render a pie chart using bokeh figure.

我使用了来自 https://docs.bokeh 的参考.org/en/latest/docs/gallery/pie_chart.html 以创建我的饼图.

I used the reference from https://docs.bokeh.org/en/latest/docs/gallery/pie_chart.html in order to create my pie chart figure.

现在,我需要在饼图的每个部分添加一个标签,代表该部分的百分比,并且标签位置应与中心对齐.

Now, I need to add on each part of the pie chart a label which represent the percentage of this part, and the label position should be align to the center.

我无法通过文档找到一种简单的方法来完成它,并尝试找到手动完成它的方法,例如以下示例:在散景中的饼图楔形中添加标签

I could not find a simple way to do it via the documentation, and try to find ways to do it manually, like this example: Adding labels in pie chart wedge in bokeh

我尝试创建一个标签集并将布局添加到绘图中,但我不知道是否有办法控制标签位置、大小和字体.text_align (right, left, center) 对我不起作用.

I tried to create a label set and add the layout to the plot but i could not figure out if there is a way to control the label position, size, and font. text_align (right, left, center) does not do the job for me.

这是我的代码 - 此函数创建并返回饼图的 htmlchart 参数包含图表的相关数据.在这种情况下,它是一个元组(大小为 1),而 series[0] 包含系列名称(series.title)、x 值列表(series.x)和 y 值列表(series.y)

Here is my code - this function create and return an html of the pie chart The chart argument contains the relevant data for the chart. in this case its a tuple (size 1), and series[0] contains the name of the series (series.title), list of x values (series.x), and list of y values (series.y)

def render_piechart(self, chart):
    """
    Renders PieChart object using Bokeh
    :param chart: Pie chart
    :return:
    """
    series = chart.series[0]
    data_dict = dict(zip(series.x, series.y))
    data = pd.Series(data_dict).reset_index(name='value').rename(columns={'index': 'Category'})
    data['angle'] = data['value'] / data['value'].sum() * 2 * pi
    data['color'] = palette[:len(series.x)]
    data['percentage'] = data['value'] / data['value'].sum() * 100
    data['percentage'] = data['percentage'].apply(lambda x: str(round(x, 2)) + '%')

    TOOLTIPS = [('Category', '@Category'), ('Value', '@value'), ('Percentage', '@percentage')]

    fig = figure(title=series.title,
                 plot_width=400 if chart.sizehint == 'medium' else 600,
                 plot_height=350 if chart.sizehint == 'medium' else 450,
                 tools='hover', tooltips=TOOLTIPS, x_range=(-0.5, 1.0))

    fig.wedge(x=0, y=1, radius=0.45, start_angle=cumsum('angle', include_zero=True),
              end_angle=cumsum('angle'), line_color='white', fill_color='color',
              legend='Category', source=data)

    fig.title.text_font_size = '20pt'

    source = ColumnDataSource(data)

    labels = LabelSet(x=0, y=1, text='percentage', level='glyph', angle=cumsum('angle', include_zero=True),
                      source=source, render_mode='canvas')

    fig.add_layout(labels)

    fig.axis.axis_label = None
    fig.axis.visible = False
    fig.grid.grid_line_color = None

    return bokeh.embed.file_html(fig, bokeh.resources.CDN) 

这是结果:饼图由三部分组成

饼图由 10 个部分组成

在 2 个示例中 - 系列标题是kuku"第一个示例的 x 和 y 值:x=["A", "B", "C"]y=[10, 20, 30]

in the 2 examples - the series title is 'kuku' x and y values for the first example: x=["A", "B", "C"] y=[10, 20, 30]

对于第二个例子:x=[A"、B"、C"、D"、E"、F"、G"、H"、I"]y=[10, 20, 30, 100, 90, 80, 70, 60, 30, 40,50]

and for the second example: x=["A", "B", "C", "D", "E", "F", "G", "H", "I"] y=[10, 20, 30, 100, 90, 80, 70, 60, 30 , 40 ,50]

我知道过去我可以用 Donut 轻松完成,但它已被弃用.我希望能够得到这样的东西:example1或者这个:example2

I know that in the past i could do it easily with Donut but it is deprecated. I want to be able to get something like this one: example1 or this: example2

推荐答案

正如你所理解的,问题在这里:

The problem, as you understand, is here:

labels = LabelSet(x=0, y=1, text='percentage', level='glyph', angle=cumsum('angle', include_zero=True), source=source, render_mode='canvas')

在散景中创建标签有点令人困惑,但仍然:你应该为你绘制的每一行添加像text_pos_x"和text_pos_y"这样的列,并用你想要放置文本的坐标填充它.然后将其应用到 LabelSet 函数中,给出 x='text_pos_x' 和 y='text_pos_y' 以便绘图的每个部分都有自己的坐标,用于放置标签:

It's a bit confusing to create labels in Bokeh, but still: you should add columns like 'text_pos_x' and 'text_pos_y' for every row you draw and fill it in with coordinates where you would like to place the text. And then apply it in LabelSet function, giving x='text_pos_x' and y='text_pos_y' so that every single part of plot have its own coordinates where to place a label:

labels = LabelSet(x='text_pos_x', y='text_pos_y', text='percentage', level='glyph', angle=0, source=source, render_mode='canvas')

是的,有必要设置角度 = 0 以避免文本被旋转.

and yes, it's necessary to set angle = 0 to avoid text being rotated.

这篇关于向散景饼图楔形添加标签的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆