散景饼图显示倒置的百分比标签
Bokeh pie chart show percentage labels upside down
我有一个按类别分组的数据框,我想生成一个包含每个类别百分比的饼图。我在 Python.
中使用 Bokeh 库
我的问题是某些百分比标签在饼图中显示不正确,如下图所示。
这是我用来生成饼图的代码:
df['angle'] = df['paymentAmount'] / df['paymentAmount'].sum() * 2 * pi
if len(df.index) > 2:
df["color"] = GnBu[len(df.index)]
elif len(df.index) == 2:
df["color"] = ["steelblue", "skyblue"]
else:
df["color"] = ["steelblue"]
df["percentage"] = df["paymentAmount"] / df["paymentAmount"].sum()
df['percentage'] = df['percentage'].astype(float).map(lambda n: '{:.2%}'.format(n))
df["percentage"] = df['percentage'].astype(str)
df["percentage"] = df["percentage"].str.pad(35, side="left")
source = ColumnDataSource(df)
p = figure(width=figsize[0], height=figsize[1], toolbar_location=None,
tooltips=[("percentage", "@percentage")],
tools="hover", x_range=(-0.5, 1.0))
pie_chart = p.wedge(x=0, y=1, radius=0.4,
start_angle=cumsum('angle', include_zero=True), end_angle=cumsum('angle'),
line_color="white", fill_color='color', source=source)
labels = LabelSet(x=0, y=1, text='percentage', angle=cumsum('angle', include_zero=True), source=source,
render_mode='canvas')
p.add_layout(labels)
legend = Legend(items=[LegendItem(label=dict(field='category'), renderers=[pie_chart])],
location=(0, figsize[1] - 100))
p.add_layout(legend, 'right')
p.axis.axis_label = None
p.axis.visible = False
p.grid.grid_line_color = None
save(p)
重现上面饼图的一些数据(制表符分隔)
category paymentAmount
Chemicals 52800.95001766206
Research 110878.70999269483
Construction 266189.2100121978
有什么解决办法吗?
提前致谢!
我发现了两个有用的 Whosebug posts 来解决这个问题:
- 在 LabelSet 中,您必须将角度设置为零,以免标签旋转 (Adding labels to bokeh pie chart wedge)
- 您必须为每个项目计算 LabelSet 的坐标(x 和 y)。为此,我使用了这个 post:adding percentage label to Bokeh Pie chart
因此,我修改了你的代码如下:
df['angle'] = df['paymentAmount'] / df['paymentAmount'].sum() * 2 * pi
value = list(df["paymentAmount"])
df["cumulative_angle"] = [(sum(value[0:i + 1]) - (item / 2)) / sum(value) * 2 * pi for i, item in enumerate(value)]
df['cos'] = np.cos(df['cumulative_angle']) * 0.3
df['sin'] = np.sin(df['cumulative_angle']) * 0.3
if len(df.index) > 2:
df["color"] = GnBu[len(df.index)]
elif len(df.index) == 2:
df["color"] = ["steelblue", "skyblue"]
else:
df["color"] = ["steelblue"]
df["percentage"] = df["paymentAmount"] / df["paymentAmount"].sum()
df['percentage'] = df['percentage'].astype(float).map(lambda n: '{:.2%}'.format(n))
df["percentage"] = df['percentage'].astype(str)
df["percentage"] = df["percentage"].str.pad(35, side="left")
source = ColumnDataSource(df)
p = figure(width=figsize[0], height=figsize[1], toolbar_location=None, x_range=(-1.0, 1.0), y_range=(-1.0, 1.0),
tooltips=[("percentage", "@percentage")], tools="hover")
pie_chart = p.wedge(x=0, y=0, radius=0.5,
start_angle=cumsum('angle', include_zero=True), end_angle=cumsum('angle'),
line_color="white", fill_color='color', source=source)
labels = LabelSet(x="cos", y="sin", y_offset=0, text='percentage', text_align="center", angle=0, source=source,
render_mode='canvas')
p.add_layout(labels)
legend = Legend(items=[LegendItem(label=dict(field="category"), renderers=[pie_chart])],
location=(0, figsize[1] - 100))
p.add_layout(legend, 'right')
p.axis.axis_label = None
p.axis.visible = False
p.grid.grid_line_color = None
save(p)
生成的饼图为:
我有一个按类别分组的数据框,我想生成一个包含每个类别百分比的饼图。我在 Python.
中使用 Bokeh 库我的问题是某些百分比标签在饼图中显示不正确,如下图所示。
这是我用来生成饼图的代码:
df['angle'] = df['paymentAmount'] / df['paymentAmount'].sum() * 2 * pi
if len(df.index) > 2:
df["color"] = GnBu[len(df.index)]
elif len(df.index) == 2:
df["color"] = ["steelblue", "skyblue"]
else:
df["color"] = ["steelblue"]
df["percentage"] = df["paymentAmount"] / df["paymentAmount"].sum()
df['percentage'] = df['percentage'].astype(float).map(lambda n: '{:.2%}'.format(n))
df["percentage"] = df['percentage'].astype(str)
df["percentage"] = df["percentage"].str.pad(35, side="left")
source = ColumnDataSource(df)
p = figure(width=figsize[0], height=figsize[1], toolbar_location=None,
tooltips=[("percentage", "@percentage")],
tools="hover", x_range=(-0.5, 1.0))
pie_chart = p.wedge(x=0, y=1, radius=0.4,
start_angle=cumsum('angle', include_zero=True), end_angle=cumsum('angle'),
line_color="white", fill_color='color', source=source)
labels = LabelSet(x=0, y=1, text='percentage', angle=cumsum('angle', include_zero=True), source=source,
render_mode='canvas')
p.add_layout(labels)
legend = Legend(items=[LegendItem(label=dict(field='category'), renderers=[pie_chart])],
location=(0, figsize[1] - 100))
p.add_layout(legend, 'right')
p.axis.axis_label = None
p.axis.visible = False
p.grid.grid_line_color = None
save(p)
重现上面饼图的一些数据(制表符分隔)
category paymentAmount
Chemicals 52800.95001766206
Research 110878.70999269483
Construction 266189.2100121978
有什么解决办法吗?
提前致谢!
我发现了两个有用的 Whosebug posts 来解决这个问题:
- 在 LabelSet 中,您必须将角度设置为零,以免标签旋转 (Adding labels to bokeh pie chart wedge)
- 您必须为每个项目计算 LabelSet 的坐标(x 和 y)。为此,我使用了这个 post:adding percentage label to Bokeh Pie chart
因此,我修改了你的代码如下:
df['angle'] = df['paymentAmount'] / df['paymentAmount'].sum() * 2 * pi
value = list(df["paymentAmount"])
df["cumulative_angle"] = [(sum(value[0:i + 1]) - (item / 2)) / sum(value) * 2 * pi for i, item in enumerate(value)]
df['cos'] = np.cos(df['cumulative_angle']) * 0.3
df['sin'] = np.sin(df['cumulative_angle']) * 0.3
if len(df.index) > 2:
df["color"] = GnBu[len(df.index)]
elif len(df.index) == 2:
df["color"] = ["steelblue", "skyblue"]
else:
df["color"] = ["steelblue"]
df["percentage"] = df["paymentAmount"] / df["paymentAmount"].sum()
df['percentage'] = df['percentage'].astype(float).map(lambda n: '{:.2%}'.format(n))
df["percentage"] = df['percentage'].astype(str)
df["percentage"] = df["percentage"].str.pad(35, side="left")
source = ColumnDataSource(df)
p = figure(width=figsize[0], height=figsize[1], toolbar_location=None, x_range=(-1.0, 1.0), y_range=(-1.0, 1.0),
tooltips=[("percentage", "@percentage")], tools="hover")
pie_chart = p.wedge(x=0, y=0, radius=0.5,
start_angle=cumsum('angle', include_zero=True), end_angle=cumsum('angle'),
line_color="white", fill_color='color', source=source)
labels = LabelSet(x="cos", y="sin", y_offset=0, text='percentage', text_align="center", angle=0, source=source,
render_mode='canvas')
p.add_layout(labels)
legend = Legend(items=[LegendItem(label=dict(field="category"), renderers=[pie_chart])],
location=(0, figsize[1] - 100))
p.add_layout(legend, 'right')
p.axis.axis_label = None
p.axis.visible = False
p.grid.grid_line_color = None
save(p)
生成的饼图为: