dopatraman
dopatraman

Reputation: 13908

Create clustered bar chart across two columns in bokeh

I have a data frame that looks like this:

       type    price1     price2
0        A     5450.0     31980.0
1        B     5450.0     20000.0
2        C     15998.0    18100.0

What I want is a clustered bar chart that plots "type" against "price". The end goal is a chart that has two bars for each type, one bar for "price1" and the other for "price2". Both columns are in the same unit ($). Using Bokeh I can group by type, but I cant seem to group by a generic "price" unit. I have this code so far:

import pandas as pd
import numpy as np
from bokeh.charts import Bar, output_file, show
from bokeh.palettes import Category20 as palette
from bokeh.models import HoverTool, PanTool
p = Bar(
        df,
        plot_width=1300,
        plot_height=900,
        label='type',
        values='price2',
        bar_width=0.4,
        legend='top_right',
        agg='median',
        tools=[HoverTool(), PanTool()],
        palette=palette[20])

But that only gets me one column for each type.enter image description here

How can I modify my code to get two bars for each type?

Upvotes: 4

Views: 4539

Answers (2)

Sohrab Rahimi
Sohrab Rahimi

Reputation: 215

Your table is "wide" format. you want to melt it to a long format first using pd.melt() function. For visualization,I suggest you use the "Seaborn" package and make your life easier. you can visualize every thing in one line.

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

your_df = pd.DataFrame(data={'type': ['A','B','C'],
      'price1':[5450, 5450, 15998],
      'price2' : [3216, 20000, 15000]})

long_df = pd.melt(your_df,id_vars = ['type'],value_vars =['price1','price2'])
print long_df

my_plot = sns.barplot(x="type", y="value",hue = "variable", data=long_df)
sns.plt.show()

enter image description here A good post on long and wide formats can be found here: Reshape Long Format Multivalue Dataframes with Pandas

if you insist on using bokeh here is how you do it as renzop pointed out :

p = Bar(long_df,
    plot_width=1000,
    plot_height=800,
    label='type',
    values='value',
    bar_width=0.4,
    group='variable',
    legend='top_right')

show(p)

Upvotes: 2

renzop
renzop

Reputation: 1316

What you are searching for is a grouped Bar plot.

But you have to reorganise your data a little bit, so that bokeh (or better Pandas) is able to group the data correctly.

df2 = pd.DataFrame(data={'type': ['A','B','C', 'A', 'B', 'C'],
          'price':[5450, 5450, 15998, 3216, 20000, 15000],
          'price_type':['price1', 'price1', 'price1', 'price2', 'price2', 'price2']})

p = Bar(
        df2,
        plot_width=1300,
        plot_height=900,
        label='type',
        values='price',
        bar_width=0.4,
        group='price_type',
        legend='top_right')
  show(p)

result

Upvotes: 4

Related Questions