One chart with two different y axis ranges in Bokeh?

后端 未结 4 1365
南旧
南旧 2020-12-07 22:54

I would like a Bar chart with Quantity information on the left y-axis, and then overlay a Scatter/Line plot with Yield % on the right. I can create each of these charts sep

相关标签:
4条回答
  • 2020-12-07 23:31

    # PEA Y PNEA ARE THE EACH OF THE LINES THAT I WANT

    p = bpl.figure(plot_width=1600, plot_height=400, 
    x_range=peas['periodos'].astype(str),toolbar_location=None)
    p.xgrid.grid_line_color = None
    p.ygrid.grid_line_color = None
    p.axis.major_label_orientation = 3.14/2
    p.yaxis.major_label_orientation = 'horizontal'
    p.outline_line_color = "White"
    
    # Eje 1
    p.line(x=peas['periodos'].astype(str),y=peas['pea'], line_dash='dashed', 
    line_width=2, legend_label='PEA', color='red')
    p.y_range = Range1d(peas['pea'].min()-1, peas['pea'].max()+1)
    
    # Eje 2
    column2_range = 'segundo y' + "_range"
    p.extra_y_ranges = {column2_range: Range1d(peas['pnea'].min()-1, 
    peas['pnea'].max()+1)
    
    
    p.line(x=peas['periodos'].astype(str), y=peas['pnea'], legend_label='PNEA', 
    y_range_name=column2_range, color="green")
    
    p.add_layout(LinearAxis(y_range_name=column2_range), "right")
    p.legend.location = "top_left"
    bpl.show(p)
    
    0 讨论(0)
  • 2020-12-07 23:38

    Yes, now it is possible to have two y axes in Bokeh plots. The code below shows script parts significant in setting up the second y axis to the usual figure plotting script.

    # Modules needed from Bokeh.
    from bokeh.io import output_file, show
    from bokeh.plotting import figure
    from bokeh.models import LinearAxis, Range1d
    
    # Seting the params for the first figure.
    s1 = figure(x_axis_type="datetime", tools=TOOLS, plot_width=1000,
               plot_height=600)
    
    # Setting the second y axis range name and range
    s1.extra_y_ranges = {"foo": Range1d(start=-100, end=200)}
    
    # Adding the second axis to the plot.  
    s1.add_layout(LinearAxis(y_range_name="foo"), 'right')
    
    # Setting the rect glyph params for the first graph. 
    # Using the default y range and y axis here.           
    s1.rect(df_j.timestamp, mids, w, spans, fill_color="#D5E1DD", line_color="black")
    
    # Setting the rect glyph params for the second graph. 
    # Using the aditional y range named "foo" and "right" y axis here. 
    s1.rect(df_j.timestamp, ad_bar_coord, w, bar_span,
             fill_color="#D5E1DD", color="green", y_range_name="foo")
    
    # Show the combined graphs with twin y axes.
    show(s1)
    

    And the plot we get looks like this:

    enter image description here

    If you want to add a label to the second axis, this can be accomplished by editing the call to LinearAxis as follows:

    s1.add_layout(LinearAxis(y_range_name="foo", axis_label='foo label'), 'right')
    
    0 讨论(0)
  • 2020-12-07 23:38

    If you have a pandas Dataframe you can use this template to plot two lines with different axis:

    from bokeh.plotting import figure, output_file, show
    from bokeh.models import LinearAxis, Range1d
    import pandas as pd
    
    # pandas dataframe
    x_column = "x"
    y_column1 = "y1"
    y_column2 = "y2"
    
    df = pd.DataFrame()
    df[x_column] = range(0, 100)
    df[y_column1] = pd.np.linspace(100, 1000, 100)
    df[y_column2] = pd.np.linspace(1, 2, 100)
    
    # Bokeh plot
    output_file("twin_axis.html")
    
    y_overlimit = 0.05 # show y axis below and above y min and max value
    p = figure()
    
    # FIRST AXIS
    p.line(df[x_column], df[y_column1], legend=y_column1, line_width=1, color="blue")
    p.y_range = Range1d(
        df[y_column1].min() * (1 - y_overlimit), df[y_column1].max() * (1 + y_overlimit)
    )
    
    # SECOND AXIS
    y_column2_range = y_column2 + "_range"
    p.extra_y_ranges = {
        y_column2_range: Range1d(
            start=df[y_column2].min() * (1 - y_overlimit),
            end=df[y_column2].max() * (1 + y_overlimit),
        )
    }
    p.add_layout(LinearAxis(y_range_name=y_column2_range), "right")
    
    p.line(
        df[x_column],
        df[y_column2],
        legend=y_column2,
        line_width=1,
        y_range_name=y_column2_range,
        color="green",
    )
    
    show(p)
    

    0 讨论(0)
  • 2020-12-07 23:40

    This post helped me to accomplish the effect you are looking for.

    Here is the content of that post:

    from bokeh.plotting import figure, output_file, show
    from bokeh.models.ranges import Range1d
    import numpy
    
    
    output_file("line_bar.html")
    
    p = figure(plot_width=400, plot_height=400)
    
    # add a line renderer
    p.line([1, 2, 3, 4, 5], [6, 7, 6, 4, 5], line_width=2)
    
    # setting bar values
    h = numpy.array([2, 8, 5, 10, 7])
    
    # Correcting the bottom position of the bars to be on the 0 line.
    adj_h = h/2
    
    # add bar renderer
    p.rect(x=[1, 2, 3, 4, 5], y=adj_h, width=0.4, height=h, color="#CAB2D6")
    
    # Setting the y  axis range   
    p.y_range = Range1d(0, 12)
    
    p.title = "Line and Bar"
    
    show(p)
    

    If you want to add the second axis to the plot do so with p.extra_y_ranges as described in the post above. Anything else, you should be able to figure out.

    For example, in my project I have code like this:

    s1 = figure(plot_width=800, plot_height=400, tools=[TOOLS, HoverTool(tooltips=[('Zip', "@zip"),('((Rides/day)/station)/capita', "@height")])],
               title="((Rides/day)/station)/capita in a Zipcode (Apr 2015-Mar 2016)")
    
    y = new_df['rides_per_day_per_station_per_capita']
    adjy = new_df['rides_per_day_per_station_per_capita']/2
    
    s1.rect(list(range(len(new_df['zip']))), adjy, width=.9, height=y, color='#f45666')
    s1.y_range = Range1d(0, .05)
    s1.extra_y_ranges = {"NumStations": Range1d(start=0, end=35)}
    s1.add_layout(LinearAxis(y_range_name="NumStations"), 'right')
    s1.circle(list(range(len(new_df['zip']))),new_df['station count'], y_range_name='NumStations', color='blue')
    show(s1)
    

    And the result is:

    0 讨论(0)
提交回复
热议问题