2015-03-01 6 views
15

Gibt es eine Möglichkeit, eine unendliche horizontale Linie mit Bokeh zu zeichnen? Die Endpunkte der Linie sollten niemals sichtbar werden, unabhängig davon, wie weit der Benutzer zoomt.Unendliche horizontale Linie in Bokeh

Dies ist, was ich bisher versucht habe. Er druckt nur eine leere Leinwand:

import bokeh.plotting as bk 
import numpy as np 

p = bk.figure() 
p.line([-np.inf,np.inf], [0,0], legend="y(x) = 0") 
bk.show(p) 

Eine Möglichkeit, die Endpunkte extrem hoch/niedrig und dem Wert des x_range und y_range sehr klein im Verhältnis zu ihnen zu setzen wäre.

import bokeh.plotting as bk 
import numpy as np 

p = bk.figure(x_range=[-10,10]) 
p.line([-np.iinfo(np.int64).max, np.iinfo(np.int64).max], [0,0], legend="y(x) = 0") 
bk.show(p) 

Allerdings hoffe ich, dass jemand eine elegantere Lösung hat.

Edit: entfernt veraltete Lösung

+1

Wenn Sie die Linie verwenden, um verschiedene Zeichnungsbereiche hervorzuheben, könnten Sie an der neuen [BoxAnnotations] (http://bokeh.pydata.org/en/latest/docs/user_guide/plotting.html#box) interessiert sein -annotationen)! – jhin

+0

Bitte denken Sie daran, die akzeptierte Antwort zu ändern, entweder 'Span' oder' BoxAnnotation' sind besser als die alte akzeptierte Antwort. – bigreddot

+0

Sie haben Recht. Beide Lösungen funktionieren gut. Ich habe die Spannweiten gewählt, weil ich denke, dass sie mehr für das gedacht sind, was ich vorhabe als unendliche Strahlen, wenn das irgendeinen Sinn ergibt. –

Antwort

19

Sie suchen "Spannweiten":

Spans (line-Typenannotationen) einen einzigen Dimension (Breite oder Höhe) und bis zum Rand der Grundstücksfläche erstrecken.

Bitte, bei http://bokeh.pydata.org/en/latest/docs/user_guide/annotations.html#spans

einen Blick der Code wird also wie folgt aussehen:

import numpy as np 
import bokeh.plotting as bk 
from bokeh.models import Span 

p = bk.figure() 

# Vertical line 
vline = Span(location=0, dimension='height', line_color='red', line_width=3) 
# Horizontal line 
hline = Span(location=0, dimension='width', line_color='green', line_width=3) 

p.renderers.extend([vline, hline]) 
bk.show(p) 

Mit dieser Lösung Benutzer erlaubt sind und nach Belieben vergrößern zu schwenken. Das Ende der Zeilen wird nie angezeigt.

+0

Ich wundere mich: Linien, Kreise und andere Glyphen können basierend auf einer" Quelle "gezeichnet werden. Wir können hier eine ColumnDataSource einspeisen. Dies ermöglicht uns, die ColumnDataSource zu ändern und somit interaktive Plots mit einem Bokeh-Server zu erstellen. Meine Frage: Funktionieren Annotationen wie Span auf die gleiche Weise? Mit anderen Worten, kann ich die vertikale Linie auch verschieben, indem ich den Wert von "location" mit einem Schieberegler verknüpfe? – Thornhale

3

Wenn Sie zwei Strahlen von der Mitte des Grundstückes werden sie nicht kleiner werden, wie Sie vergrößern oder verkleinern, da die Länge in Pixel. Also etwas in der Art:

p.ray(x=[0],y=[0],length=300, angle=0, legend="y(x) = 0") 
p.ray(x=[0],y=[0],length=300, angle=np.pi, legend="y(x) = 0") 

Aber wenn der Benutzer in beide Richtungen schwenkt, wird das Ende des Strahls angezeigt. Wenn Sie verhindern können, dass der Benutzer überhaupt schwenkt (auch wenn er zoomt), ist dies ein etwas besserer Code für eine horizontale Linie.

Wenn der Benutzer in der Lage ist zu zoomen und zu schwenken, wo es ihnen gefällt, gibt es keinen guten Weg (soweit ich das beurteilen kann), eine horizontale Linie zu erhalten, wie Sie beschreiben.

+0

Danke!Mit ein wenig Modifikation macht der Strahl den Trick. Ich bearbeite meine Frage. Es ist jedoch keineswegs elegant. –

+0

Diese Antwort sollte jetzt ersetzt werden, da 'Spans' verfügbar sind – bigreddot

7

Die Bokeh documentation on segments and rays gibt die folgende Lösung (unter Verwendung von ray):

Um einen „unendlichen“ ray zu haben, das immer an der Kante des Grundstück erstreckt, 0 für die Länge angeben.

Und in der Tat, der folgende Code erzeugt eine unendliche, horizontale Linie:

import numpy as np 
import bokeh.plotting as bk 
p = bk.figure() 
p.ray(x=[0], y=[0], length=0, angle=0, line_width=1) 
p.ray(x=[0], y=[0], length=0, angle=np.pi, line_width=1) 
bk.show(p)