1

I'm trying to achieve the following o/p from bokeh which is deprecated now. In the new structure, I need to layer everything like working in HTML. Is there any simplified example like this bokeh pie chart(deprecated) ?enter image description here

3
  • I'm not aware of a single "combined" example but there is a basic Pie chart example here (docs.bokeh.org/en/latest/docs/examples/topics/pie/pie.html) and a Donut chart example here (docs.bokeh.org/en/latest/docs/examples/topics/pie/donut.html) so you would more or less just combine those two examples to get a chart like the one above. Commented Jan 9, 2023 at 20:09
  • @bigreddot Thanks for the reply. I thought about that. But it's not an easy one like before. That's why I tried here. Commented Jan 10, 2023 at 2:02
  • Well, the "easy on from before" was part of bokeh.charts which was barely functional and did not have a maintainer, so it had to be jettisoned from the main library. If you want to simplify things, it's probably possible to use annular_wedge with inner_radius=0 for the inner wedges, so that all levels can be created consistently. There might be higher level tools (e.g. holoviews or pandas-bokeh) that offer a multi-level pie chart, but I'm not sure. Commented Jan 10, 2023 at 17:08

1 Answer 1

1

You can combine wegde and annular_wedge

The example code below creates this figure:

medal cake

Example code

Pandas

Lets say we have this data table for the medals of a sport event.

import numpy as np import pandas as pd df = pd.DataFrame({ 'Country':['Fra', 'Deu', 'Can', 'USA'], 'Gold': [0,1,2,3], 'Silver': [1,2,2,2], 'Bronze':[3,2,1,3] }) >>> df Country Gold Silver Bronze 0 FRA 0 1 3 1 GER 1 2 2 2 CAN 2 2 1 3 USA 3 2 3 

Now we have to calculate the angles to use the bokeh wedges. We use a copy to not overwrite the original data.

# get a copy and calculate the angles _df = df.copy() _df['Country_total'] = _df[['Gold', 'Silver', 'Bronze']].sum(axis=1) total_sum = _df['Country_total'].sum() _df["End"] = _df['Country_total'].div(total_sum).mul(2 * np.pi).cumsum().round(6) _df["Start"] = _df["End"].shift(1).fillna(0) _df['Color'] = ['blue', 'red', 'green', 'magenta'] _df 

Bokeh

Here we loop over all rows of the DataFrame and draw the annular wedge first and then the inner wedge to get the correct color in the legend.

from bokeh.models import Legend from bokeh.plotting import show, figure, output_notebook output_notebook() p = figure(width=400, height=300, match_aspect=True, x_range=(-2.2,2.2), y_range=(-2.2,2.2)) p.add_layout( Legend( click_policy="hide", margin=1, ), "right", ) p.rect(x=0, y=0, width=2, height=2, alpha=0) wedges = [] for i, item in _df.iterrows(): start = item["Start"] end = item["End"] start_angle = start end_angle = start for value, color in zip(['Gold', 'Silver', 'Bronze'], ['gold', 'silver', '#bf8970']): angle = np.round(item[value] / total_sum * 2 * np.pi, 6) end_angle += angle p.annular_wedge( x=0, y=0, inner_radius=1, outer_radius=2, start_angle=start_angle, end_angle=end_angle, color=color, line_color='white', legend_label=item['Country'], ) start_angle += angle p.wedge( x=0, y=0, radius=1, start_angle=start, end_angle=end, color=item["Color"], line_color='white', legend_label=item['Country'], ) p.xgrid.visible = False p.ygrid.visible = False show(p) 

Comment

I hope this is close tou your wanted solution.

Sign up to request clarification or add additional context in comments.

1 Comment

thanks for your reply. I'm expecting something similar to the previous one. As I said earlier, Here we're doing everything like a designer. Instead, if we have a codebase like the previous one, it'll be easy to use.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.