在散景 2.x 中使用 annual_wedge 在 pie/donut 图表中添加标签
Adding labels in pie/donut chart using annual_wedge in bokeh 2.x
我在将正确对齐的标签集应用到使用散景中的 annual_wedge
字形创建的甜甜圈样式图表时遇到问题。
我无法对齐属于甜甜圈图 "rings" 类别的标签 "horizontaly",其中 horizontaly 是来自 inner_radius
的标签的对齐方式14=] 到 outer_radius
。
目前标签集似乎没有对应于 annual_wedge
的 inner_radius
设置,这使得将标签集应用和对齐到年度楔形非常困难。
我正在按照 中的示例使用字符串填充,但这似乎是水平移动标签的非常肮脏的技巧。
如何以与 annual_wedge 字形的 inner_radius 对应的对齐方式将标签应用于 annual_wedge?
这是我的代码示例:
# > gics_sector_data
gics_sector_data["gics_name"] = gics_sector_data["gics_name"].astype(str)
gics_sector_data["gics_name"] = gics_sector_data["gics_name"].str.pad(47, side = "left")
# Sector Ring
p.annular_wedge(x=9, y=9, inner_radius=0.8,outer_radius=2.5,
start_angle=cumsum('angle', include_zero=True), end_angle=cumsum('angle'),
line_color="white", fill_color='color', source=gics_sector_data)
sourceSector = ColumnDataSource(gics_sector_data)
labelsSector = LabelSet(x=9, y=9, text='gics_name',
angle=cumsum('angle', include_zero=True), source=sourceSector, render_mode='canvas',
text_font_size="8pt", text_align='left',background_fill_color='white')
p.add_layout(labelsSector)
在图片中,我将标签的背景颜色设置为白色,这样可以更好地看到标签的对齐方式和间距。
]
仅供参考:这是要显示的数据Global Industry Classification Standard
您必须自己计算坐标。
扩展链接示例:
from math import pi
import numpy as np
import pandas as pd
from bokeh.io import show
from bokeh.models import LabelSet, ColumnDataSource
from bokeh.palettes import Category20c
from bokeh.plotting import figure
x = {'United States': 157,
'United Kingdom': 93,
'Japan': 89,
'China': 63,
'Germany': 44,
'India': 42,
'Italy': 40,
'Australia': 35,
'Brazil': 32,
'France': 31,
'Taiwan': 31,
'Spain': 29}
R = 0.4
data = (pd.Series(x)
.reset_index(name='value')
.rename(columns={'index': 'country'})
.assign(end_angle=lambda d: np.cumsum(d['value'] / d['value'].sum() * 2 * pi),
start_angle=lambda d: np.pad(d['end_angle'], (1, 0))[:-1],
color=Category20c[len(x)],
label_x=lambda d: R * 0.95 * np.cos(d['start_angle']),
label_y=lambda d: R * 0.95 * np.sin(d['start_angle'])))
source = ColumnDataSource(data)
p_range = (-R * 1.2, R * 1.2)
p_size = 500
p = figure(plot_height=p_size, plot_width=p_size, toolbar_location=None,
x_range=p_range, y_range=p_range,
tools="hover", tooltips="@country: @value")
for r in [p.xaxis, p.yaxis, p.grid]:
r.visible = False
p.wedge(x=0, y=0, radius=R,
start_angle='start_angle', end_angle='end_angle',
line_color="white", fill_color='color', legend_label='country', source=source)
p.add_layout(LabelSet(x='label_x', y='label_y', text='value', text_align='right',
angle='start_angle', source=source, render_mode='canvas'))
show(p)
多亏了 Eugene,我才走上了启蒙之路,并且能够得到我想要的图表。
我不得不通过计算 "donut" 扇区的起始角和结束角之间的中间值来修改标签位置的计算,因为我想让标签位于每个楔形的中间。
我修改了 Eugene 的例子,其中 "num" 只是我用来计算每个 annual_wedge 的相对宽度的值(Eugene 在他的例子中使用 'value',我使用 num对于 'donut' 上总共类似宽度的插槽中每个楔形占用的插槽数,我希望这足够清楚):
R = 3
gics_sector_data= gics_sector_data.assign(
end_angle=lambda d: np.cumsum(d['num'] / d['num'].sum() * 2 * pi),
start_angle=lambda d: np.pad(d['end_angle'], (1, 0))[:-1],
label_x=lambda d: R* 1.00 * np.cos(((d['end_angle']-d['start_angle'])/2)+d['start_angle']),
label_y=lambda d: R* 1.00 * np.sin(((d['end_angle']-d['start_angle'])/2)+d['start_angle']),
label_angle=lambda d: (((d['end_angle']-d['start_angle'])/2)+d['start_angle']))
关于 1.00 乘法,您可以将标签从楔形的外边缘移开 f.e。使用 0.95.
除此之外:我通过添加 label_shortname 列来缩短标签名称,因为散景不能换行标签。短名称将用于标签,长名称用于工具提示:
gics_sector_data['gics_name_short'] = gics_sector_data['gics_name'].str.slice(stop=20)
然后像 start_angles 和 end_anglescalculated 一样绘制 annual_wedge:
# Sector Ring
p.annular_wedge(x=0, y=0, inner_radius=gics_sector_radius-ringWidth, outer_radius=gics_sector_radius,
start_angle='start_angle', end_angle='end_angle',
line_color="white", fill_color='color', source=gics_sector_data)
最后用计算出的label_x、label_y和label_angle绘制LabelSet,将在楔形中间绘制标签,text_baseline='middle' 是获得良好结果所必需的:
sourceSector = ColumnDataSource(gics_sector_data)
labelsSector = LabelSet(x='label_x', y='label_y', text='gics_name_short',
angle='label_angle', source=sourceSector, render_mode='canvas',
text_font_size="7pt", text_align='right', text_baseline='middle')
p.add_layout(labelsSector)
这里是 99.999% 的完美结果GICS result bokeh chart,我希望这有助于创建类似的图表
我在将正确对齐的标签集应用到使用散景中的 annual_wedge
字形创建的甜甜圈样式图表时遇到问题。
我无法对齐属于甜甜圈图 "rings" 类别的标签 "horizontaly",其中 horizontaly 是来自 inner_radius
的标签的对齐方式14=] 到 outer_radius
。
目前标签集似乎没有对应于 annual_wedge
的 inner_radius
设置,这使得将标签集应用和对齐到年度楔形非常困难。
我正在按照
如何以与 annual_wedge 字形的 inner_radius 对应的对齐方式将标签应用于 annual_wedge?
这是我的代码示例:
# > gics_sector_data
gics_sector_data["gics_name"] = gics_sector_data["gics_name"].astype(str)
gics_sector_data["gics_name"] = gics_sector_data["gics_name"].str.pad(47, side = "left")
# Sector Ring
p.annular_wedge(x=9, y=9, inner_radius=0.8,outer_radius=2.5,
start_angle=cumsum('angle', include_zero=True), end_angle=cumsum('angle'),
line_color="white", fill_color='color', source=gics_sector_data)
sourceSector = ColumnDataSource(gics_sector_data)
labelsSector = LabelSet(x=9, y=9, text='gics_name',
angle=cumsum('angle', include_zero=True), source=sourceSector, render_mode='canvas',
text_font_size="8pt", text_align='left',background_fill_color='white')
p.add_layout(labelsSector)
在图片中,我将标签的背景颜色设置为白色,这样可以更好地看到标签的对齐方式和间距。
仅供参考:这是要显示的数据Global Industry Classification Standard
您必须自己计算坐标。
扩展链接示例:
from math import pi
import numpy as np
import pandas as pd
from bokeh.io import show
from bokeh.models import LabelSet, ColumnDataSource
from bokeh.palettes import Category20c
from bokeh.plotting import figure
x = {'United States': 157,
'United Kingdom': 93,
'Japan': 89,
'China': 63,
'Germany': 44,
'India': 42,
'Italy': 40,
'Australia': 35,
'Brazil': 32,
'France': 31,
'Taiwan': 31,
'Spain': 29}
R = 0.4
data = (pd.Series(x)
.reset_index(name='value')
.rename(columns={'index': 'country'})
.assign(end_angle=lambda d: np.cumsum(d['value'] / d['value'].sum() * 2 * pi),
start_angle=lambda d: np.pad(d['end_angle'], (1, 0))[:-1],
color=Category20c[len(x)],
label_x=lambda d: R * 0.95 * np.cos(d['start_angle']),
label_y=lambda d: R * 0.95 * np.sin(d['start_angle'])))
source = ColumnDataSource(data)
p_range = (-R * 1.2, R * 1.2)
p_size = 500
p = figure(plot_height=p_size, plot_width=p_size, toolbar_location=None,
x_range=p_range, y_range=p_range,
tools="hover", tooltips="@country: @value")
for r in [p.xaxis, p.yaxis, p.grid]:
r.visible = False
p.wedge(x=0, y=0, radius=R,
start_angle='start_angle', end_angle='end_angle',
line_color="white", fill_color='color', legend_label='country', source=source)
p.add_layout(LabelSet(x='label_x', y='label_y', text='value', text_align='right',
angle='start_angle', source=source, render_mode='canvas'))
show(p)
多亏了 Eugene,我才走上了启蒙之路,并且能够得到我想要的图表。 我不得不通过计算 "donut" 扇区的起始角和结束角之间的中间值来修改标签位置的计算,因为我想让标签位于每个楔形的中间。
我修改了 Eugene 的例子,其中 "num" 只是我用来计算每个 annual_wedge 的相对宽度的值(Eugene 在他的例子中使用 'value',我使用 num对于 'donut' 上总共类似宽度的插槽中每个楔形占用的插槽数,我希望这足够清楚):
R = 3
gics_sector_data= gics_sector_data.assign(
end_angle=lambda d: np.cumsum(d['num'] / d['num'].sum() * 2 * pi),
start_angle=lambda d: np.pad(d['end_angle'], (1, 0))[:-1],
label_x=lambda d: R* 1.00 * np.cos(((d['end_angle']-d['start_angle'])/2)+d['start_angle']),
label_y=lambda d: R* 1.00 * np.sin(((d['end_angle']-d['start_angle'])/2)+d['start_angle']),
label_angle=lambda d: (((d['end_angle']-d['start_angle'])/2)+d['start_angle']))
关于 1.00 乘法,您可以将标签从楔形的外边缘移开 f.e。使用 0.95.
除此之外:我通过添加 label_shortname 列来缩短标签名称,因为散景不能换行标签。短名称将用于标签,长名称用于工具提示:
gics_sector_data['gics_name_short'] = gics_sector_data['gics_name'].str.slice(stop=20)
然后像 start_angles 和 end_anglescalculated 一样绘制 annual_wedge:
# Sector Ring
p.annular_wedge(x=0, y=0, inner_radius=gics_sector_radius-ringWidth, outer_radius=gics_sector_radius,
start_angle='start_angle', end_angle='end_angle',
line_color="white", fill_color='color', source=gics_sector_data)
最后用计算出的label_x、label_y和label_angle绘制LabelSet,将在楔形中间绘制标签,text_baseline='middle' 是获得良好结果所必需的:
sourceSector = ColumnDataSource(gics_sector_data)
labelsSector = LabelSet(x='label_x', y='label_y', text='gics_name_short',
angle='label_angle', source=sourceSector, render_mode='canvas',
text_font_size="7pt", text_align='right', text_baseline='middle')
p.add_layout(labelsSector)
这里是 99.999% 的完美结果GICS result bokeh chart,我希望这有助于创建类似的图表