pandas 如何在 Bokeh (Python) 中绘制水平条形图

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33737079/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 00:14:37  来源:igfitidea点击:

How to plot Horizontal Bar Chart in Bokeh (Python)

pythonpandasmatplotlibbokehseaborn

提问by Afloz

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 Seabornand it looks great.

我已经使用Seaborn它绘制了它,它看起来很棒。

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')

enter image description here

在此处输入图片说明

However, I'll like to embed this is a Flask web app using Bokeh.

但是,我想使用Bokeh.

I couldn't find an horizontal barplotin Bokeh. Even flipping the xand yaxis do not seem to work. This is what I've done: * Transposed df_datafrom 9x1to 1x9. Yet, I'm still not getting anything remotely nice.

我找不到horizontal barplotin Bokeh。即使翻转xy轴似乎也不起作用。这就是我所做的: *df_data9x11x9. 然而,我仍然没有得到任何好的东西。

bar = Bar(df_data.transpose(), df_data.columns.tolist(), stacked=False, responsive=True)

script, div = components(bar)

enter image description here

在此处输入图片说明

Notice that I still do not have Horizontaland my categoryaxis is messed up.

请注意,我仍然没有Horizontal并且我的category轴搞砸了。

Can anyone help modify this further?

任何人都可以帮助进一步修改吗?

回答by jarno

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.

使用 rect 字形很容易做到。请注意,当您使用分类值设置 y_range 时,散景图中这些值的索引从 1 开始。这就是计数器“j”从 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)

enter image description here

在此处输入图片说明

回答by PiWi

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.

您可以使用 rect 或quad glyphs进行低级别并重建水平条形图。上面的代码是暂定的,在 y 轴上缺少城市标签(现在没有时间了......)。但我希望这会有所帮助。

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")

回答by Leb

AFAIK there isn't one. This is the closest mention to it that I know of being #1856. For now only vertical bar chartsare available:

AFAIK 没有。这是我所知道的最接近它的提及#1856。现在只有竖条图表可供选择:

Bar Graph aka Horizontal Bar Graph (we currently don't have a chartfor)

Column Graph aka Vertical Bar Graph (currently Bar)

条形图又名水平条形图(我们目前没有图表)

柱形图又名垂直条形图(目前为条形图)

Side Note: Transposing the data will work as you have tried, that is expected.

旁注:转置数据将按照您的尝试工作,这是预期的。

回答by euri10

I think there is none. One hack could be to use a custom css with rotate() http://www.w3schools.com/css/css3_2dtransforms.asp

我认为没有。一种技巧可能是使用带有rotate() http://www.w3schools.com/css/css3_2dtransforms.asp的自定义css