Choosing order of bars in Bokeh bar chart

2019-03-30 00:42发布

As part of trying to learn to use Bokeh I am trying to make a simple bar chart. I am passing the labels in a certain order (days of the week) and Bokeh seems to be sorting them alphabetically. How can I have the bars show up in the order of the original list?

from bokeh.plotting import show
from bokeh.io import output_notebook
from bokeh.charts import Bar
from collections import OrderedDict
import calendar 

output_notebook()

data = OrderedDict()
data['values'] = [2,3,4,5,6,7,8] #values only ascending to make correct graph clear
data['days'] = [calendar.day_name[i-1] for i in range(7)]
p = Bar(data, label='days', values='values', 
         title='OrderedDict Input',xlabel="Day", ylabel="Value")
show(p)

Output generated

4条回答
Viruses.
2楼-- · 2019-03-30 01:26

I am no big fan of high level charts such as Bar plots. They are not very customizable. Building them 'by hand' is often easier -and not necessary much longer. This is what I would do:

from bokeh.plotting import figure
from bokeh.io import output_file, show
import calendar

values = [2,3,4,5,6,7,8]
days = [calendar.day_name[i-1] for i in range(1,8)]

p = figure(x_range=days)
p.vbar(x=days, width=0.5, top=values, color = "#ff1200")

output_file('foo.html')
show(p)

which yields:

enter image description here

查看更多
Animai°情兽
3楼-- · 2019-03-30 01:28

In general, with any plot you should be able to specify the x (or y) range explicitly. tk's answer is helpful if you want to completely disregard the Bar chart class (which, for reasons mentioned, is not the worst idea in the world). user666's answer is helpful if your data columns are already ordered the way you want them. Otherwise you can specify the order yourself:

Week starts on Sunday:

from bokeh.models import FactorRange
...
p.x_range = FactorRange(factors=data['days'])

Sunday start

Week starts on Monday:

p.x_range = FactorRange(factors=data['days'][1:] + [data['days'][0]])

enter image description here

查看更多
Ridiculous、
4楼-- · 2019-03-30 01:32

This is a comment related to the answer from user666 (I don't have sufficient credits to add comments.)

I don't think the use of OrderedDict is helping here, as it remembers only the order that keys were inserted (i.e. 'values' comes before 'days'), and not the order of sequences that are the values associated with those keys.

Also FYI there is a discussion of this issue on the bokeh GitHub site here: https://github.com/bokeh/bokeh/issues/2924 and here: https://github.com/bokeh/bokeh/pull/3623

查看更多
兄弟一词,经得起流年.
5楼-- · 2019-03-30 01:40

Note from Bokeh project maintainers: This answer refers to an obsolete and deprecated API that should not be used in any new code. For information about creating bar charts with modern and fully supported Bokeh APIs, see other responses.


Here's how to retain original order of the labels in your example using the Charts interface, tested with Bokeh 0.11.1.

from bokeh.plotting import show
from bokeh.io import output_notebook
from bokeh.charts import Bar
from collections import OrderedDict
import calendar 
from bokeh.charts.attributes import CatAttr

output_notebook()

data = OrderedDict()
data['values'] = [2,3,4,5,6,7,8] #values only ascending to make correct graph clear
data['days'] = [calendar.day_name[i-1] for i in range(7)]
p = Bar(data, label=CatAttr(columns=['days'], sort=False), 
        values='values',title='OrderedDict Input',xlabel="Day", ylabel="Value")
show(p)
查看更多
登录 后发表回答