我有一个按类别分组的数据框,我想生成一个包含每个类别百分比的饼图。我在 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
任何想法如何解决这个问题?
先谢谢你!
答案 0 :(得分:3)
我找到了两个有用的 StackOverflow 帖子来解决这个问题:
因此,我将您的代码修改如下:
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)
生成的饼图为: