I have this data:
data = {'Cities': {'Des_Moines': 80.0, 'Lubbock': -300.0, 'Minneapolis': 85.7,
'Orange_County': 80.0, 'Salt_Lake_City': 81.8, 'San_Diego': 80.0,
'San_Francisco': -400.0, 'Troy': -400.0, 'Wilmington': -300.0}}
I have plotted this using Seaborn and it looks great.
df_data = pd.DataFrame(data).sort_values('Cities', ascending=False)
sns.barplot(x='Cities', y=df_data.index, data=df_data, label='Cities', palette='Greens')

However, I'll like to embed this is a Flask web app using Bokeh.
I couldn't find an horizontal barplot in Bokeh. Even flipping the x and y axis do not seem to work. This is what I've done:
* Transposed df_data from 9x1 to 1x9. Yet, I'm still not getting anything remotely nice.
bar = Bar(df_data.transpose(), df_data.columns.tolist(), stacked=False, responsive=True)
script, div = components(bar)

Notice that I still do not have Horizontal and my category axis is messed up.
Can anyone help modify this further?
It's pretty easy to do with rect glyphs. Note that when you set the y_range with categorical values, the indexing of these in the bokeh plot starts at 1. That's why the counter "j" starts at 1.
import numpy as np
import pandas as pd
from bokeh.plotting import figure, show
from bokeh.models import Range1d
data = {'Cities': {'Des_Moines': 80.0, 'Lubbock': -300.0, 'Minneapolis': 85.7,
'Orange_County': 80.0, 'Salt_Lake_City': 81.8, 'San_Diego': 80.0,
'San_Francisco': -400.0, 'Troy': -400.0, 'Wilmington': -300.0}}
#df_data = pd.DataFrame(data).sort_values('Cities', ascending=False)
df_data = pd.DataFrame(data).sort(columns='Cities',ascending=False)
this_series = df_data.loc[:,'Cities']
p = figure(width=800, height=600, y_range=this_series.index.tolist())
p.background_fill = "#EAEAF2"
p.grid.grid_line_alpha=1.0
p.grid.grid_line_color = "white"
p.xaxis.axis_label = 'xlabel'
p.xaxis.axis_label_text_font_size = '14pt'
p.xaxis.major_label_text_font_size = '14pt'
#p.x_range = Range1d(0,50)
#p.xaxis[0].ticker=FixedTicker(ticks=[i for i in xrange(0,5,1)])
p.yaxis.major_label_text_font_size = '14pt'
p.yaxis.axis_label = 'ylabel'
p.yaxis.axis_label_text_font_size = '14pt'
j = 1
for k,v in this_series.iteritems():
print k,v,j
p.rect(x=v/2, y=j, width=abs(v), height=0.4,color=(76,114,176),
width_units="data", height_units="data")
j += 1
show(p)

You can go for the low level and reconstruct an horizontal bar plot using rect or quad glyphs. The above code is tentative and lack cities labels on y axis (no more time now...). But I hope this can help.
data = {'Cities': {'Des_Moines': 80.0, 'Lubbock': -300.0, 'Minneapolis': 85.7,
'Orange_County': 80.0, 'Salt_Lake_City': 81.8, 'San_Diego': 80.0,
'San_Francisco': -400.0, 'Troy': -400.0, 'Wilmington': -300.0}}
from bokeh.plotting import figure, show
from bokeh.models import Range1d
from bokeh.palettes import Greens9
import numpy as np
cities = data['Cities']
p = figure(width=400, height=400)
bottom = -1
ii = -1
for k,v in cities.iteritems():
bottom = bottom+1
top = bottom+1
left = 0
right = cities[k]
ii += 1
p.quad(top=top, bottom=bottom, left=left,
right=right, color=Greens9[ii]) #"#B3DE69")
min_city = min(cities, key=cities.get)
max_city = max(cities, key=cities.get)
p.x_range = Range1d(start=cities[min_city], end=cities[max_city])
show(p)
# Can be done with rect glyph:
#p = figure(width=400, height=400)
#p.rect(x=[1, 2, 3], y=[1, 2, 3], width=0.2, height=40, color="#CAB2D6",
# angle=np.pi/2, height_units="screen")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With