简体   繁体   中英

Python bokeh bar chart with nominal / categorical x-axis + twin y-axis

How can I create a plot with bokeh that is a Bar chart and has left and right y-axis ? I want to plot two columns from a dataframe, where the row ID is categorical and it should be the x-axis . Wint only one y-axis , Bar works well but I don't know how to add extra_y_ranges to a Bar chart or better to say I can create extra_y_ranges but I cannot use add_layout at Bar chart. And I cannot plot my dataframe columns in the way that the first column would relate to the left y-axis and the second column would relate to the right y-axis .

I tried to create bar chart manually with figure.quad . I had to use x_range=my_df.index because I need categorical x-axis . I use the same values at left and right parameters and I use line_width=7 not to have a single line but a bar. But I have to shift my bars a bit to left becasue I want to plot my second attribute on the same categorical IDs. So my question is: How can I shift a plot to left/right?

Here is a sample example what I do:

from bokeh.plotting import figure, output_file, show
from bokeh.models import LinearAxis, Range1d

output_file("bars.html")

p = figure(title="twin y-axis bar example", x_range=['0','4','2'])

p.quad(bottom=0, top=[70,60,50], left=['0','4','2'], right=['0','4','2']
    , line_width=7, line_color='red')

p.extra_y_ranges = {'foo':Range1d(start=0, end=20)}
p.add_layout(LinearAxis(y_range_name='foo', axis_label='right_y_axis'), place='right')

p.quad(bottom=0, top=[15,10,5], left=['0','4','2'], right=['0','4','2']
    , line_width=7, line_color='blue', y_range_name='foo')

show(p)

So I want to shift a bit left the red bar and a bit right the blue bar not to cover each other.

Thank you!!!

I was able to "solve" this problem in a horrible way: I created lots of empty categories (different number of spaces in their names). In my example it looks not too nice but if somebody has more categories (eg >10) then it can look like a real normal bar chart. Of course these empty categories can be generated easily using dataframe methods but in my example code I use only lists. Here is my code:

from bokeh.plotting import figure, output_file, show
from bokeh.models import LinearAxis, Range1d

output_file("bars.html")

p = figure(title="twin y-axis bar example", x_range=['','0','',' ','4',' '
    ,'  ','2','  ','   ','7','   ','    ','3','    ','     ','1','     '])

p.quad(bottom=0, top=[70,68,50,48,30,28], left=['',' ','  ','   ','    ','     ']
    , right=['',' ','  ','   ','    ','     '], line_width=7, line_color='red')

p.yaxis.axis_label = 'left y axis'
p.yaxis.axis_label_text_color = 'red'

p.extra_y_ranges = {'foo':Range1d(start=-1, end=21)}
p.add_layout(LinearAxis(y_range_name='foo', axis_label='right y axis'
    , axis_label_text_color='blue'), place='right')

p.quad(bottom=0, top=[18,15,12,9,6,3], left=['0','4','2','7','3','1']
    , right=['0','4','2','7','3','1'], line_width=7, line_color='blue', y_range_name='foo')

p.xaxis.axis_label = 'x axis'
p.xaxis.axis_label_standoff = -5

show(p)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM