1

My Dataframe

I have a Dataframe and I want to group by Type, and then Flag and plot a graph for count of ID and another graph grouped by Type , Flag and sum of Total column in Bokeh. ')

 p.hbar(df,
   plot_width=800,
   plot_height=800,
   label='Type',
   values='ID',
   bar_width=0.4,
   group = ' Type', 'Flag'
   legend='top_right')
 [![Expected Graph ][2]][2]

If it's not possible with Bokeh what other package can I use to get a good looking graph( Vibrant colours with white background)

0

1 Answer 1

2

You can do this with the holoviews library, which uses bokeh as a backend.

import pandas as pd
import holoviews as hv
from holoviews import opts
hv.extension("bokeh")

df = pd.DataFrame({
    "type": list("ABABCCAD"),
    "flag": list("YYNNNYNY"),
    "id": list("DEFGHIJK"),
    "total": [40, 100, 20, 60, 77, 300, 60, 50]
})

# Duplicate the dataframe
df = pd.concat([df] * 2)
print(df)
  type flag  id  total
0    A    Y   1     40
1    B    Y   2    100
2    A    N   3     20
3    B    N   4     60
4    C    N   5     77
5    C    Y   6    300
6    A    N   7     60
7    D    Y   8     50

Now that we have our data, lets work on plotting it:

def mainplot_hook(plot, element):
    plot.state.text(
        y="xoffsets", 
        x="total", 
        text="total", 
        source=plot.handles["source"],
        text_align="left",
        y_offset=9,
        x_offset=5
    )
    
def sideplot_hook(plot, element):
    plot.state.text(
        y="xoffsets", 
        x="count", 
        text="count", 
        source=plot.handles["source"],
        text_align="left",
        y_offset=9,
        x_offset=5
    )
    
# Create single bar plot for sum of the total column
total_sum = df.groupby(["type", "flag"])["total"].sum().reset_index()
total_sum_bars = hv.Bars(total_sum, kdims=["type", "flag"], vdims="total")

# Create our multi-dimensional bar plot
all_ids = sorted(df["id"].unique())
counts = df.groupby(["type", "flag"])["id"].value_counts().rename("count").reset_index()
id_counts_hmap = hv.Bars(counts, kdims=["type", "flag", "id"], vdims="count").groupby("type")


main_plot = (total_sum_bars
             .opts(hooks=[mainplot_hook], 
                   title="Total Sum", 
                   invert_axes=True)
)

side_plots = (
        id_counts_hmap
        .redim.values(id=all_ids, flag=["Y", "N"])
        .redim.range(count=(0, 3))
        .opts(
            opts.NdLayout(title="Counts of ID"), 
            opts.Bars(color="#1F77B4", height=250, width=250, invert_axes=True, hooks=[sideplot_hook]))
        .layout("type")
        .cols(2)
)

final_plot = main_plot + side_plots

# Save combined output as html
hv.save(final_plot, "my_plot.html")

# Save just the main_plot as html
hv.save(main_plot, "main_plot.html")

enter image description here As you can see, the code to make plots in holoviews can be a little tricky but it's definitely a tool I would recommend you pick up. Especially if you deal with high dimensional data regularly, it makes plotting it a breeze once you get the syntax down.

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

19 Comments

Thanks . How do I make a horizontal bar? Does hbar work here
To make a horizontal bar in holoviews, just pass invert_axes=True to the call to opts. To make the plot on the left horizontal bars do: total_sum_bars.opts(title="Total Sum", invert_axes=True) Then to change the bars on the right, you'll need to pass it into opts.Bars(..., invert_axes=True)
Which function should I add the total value of each bar. I want to show the total value of each bar on the image..
Also I cant see the plot on the spyder console, is there nay way to save only the final plot separtely as image or pdf.? It shows me only :HoloMap [day] :Bars [flag,size] (count) in the console
holoviews doesnt yet properly handle Text with nested bar plots, so you'll need to write your own hook to add it to the underlying bokeh backend. see updated answer. Also you can show your plot by calling bokeh.io.show on the rendered bokeh object as well.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.