web-dev-qa-db-de.com

Ein Diagramm mit zwei verschiedenen y-Achsenbereichen in Bokeh?

Ich möchte ein Balkendiagramm mit Mengeninformationen auf der linken Y-Achse und dann ein Scatter/Line-Diagramm mit Ertrag% auf der rechten Seite überlagern. Ich kann jedes dieser Diagramme separat erstellen, weiß jedoch nicht, wie ich es zu einer einzelnen Grafik kombinieren soll.

In matplotlib erstellen wir eine zweite Figur mit twinx() und verwenden dann yaxis.tick_left() und yaxis.tick_right() für die jeweiligen Figuren.

Gibt es eine Methode, mit Bokeh etwas Ähnliches zu tun?

27
brent5000

Ja, jetzt können zwei Y-Achsen in Bokeh-Plots verwendet werden .. Der folgende Code zeigt Skriptteile, die für das Einrichten der zweiten Y-Achse von Bedeutung sind.

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

Und die Handlung, die wir bekommen, sieht so aus:

enter image description here

Wenn Sie ein Label zur zweiten Achse hinzufügen möchten , können Sie den Aufruf von LinearAxis folgendermaßen bearbeiten: 

s1.add_layout(LinearAxis(y_range_name="foo", axis_label='foo label'), 'right')
34
tomaskazemekas

Dieser Beitrag hat mir geholfen, den gewünschten Effekt zu erzielen.

Hier ist der Inhalt dieses Beitrags:

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)

 enter image description here

Wenn Sie die zweite Achse zur Grafik hinzufügen möchten, verwenden Sie p.extra_y_ranges wie im obigen Beitrag beschrieben. Alles andere sollten Sie herausfinden können.

In meinem Projekt habe ich zum Beispiel folgenden Code:

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)

Und das Ergebnis ist:

 enter image description here

7
Ken Myers

Wenn Sie einen Pandas-Datenrahmen haben, können Sie diese Vorlage verwenden, um zwei Linien mit unterschiedlichen Achsen zu zeichnen:

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)

 enter image description here

0
Roman Orac