Infinite horizontal line in Bokeh

爱⌒轻易说出口 提交于 2019-12-03 15:14:10

问题


Is there a way to plot an infinite horizontal line with Bokeh? The endpoints of the line should never become visible, no matter how far out the user is zooming.

This is what I've tried so far. It just prints an empty canvas:

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)

One way would be to set the endpoints extremely high/low and the figure's x_range and y_range very small in relation to them.

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)

However, I am hoping that somebody has a more elegant solution.

Edit: removed outdated solution


回答1:


You are looking for "spans":

Spans (line-type annotations) have a single dimension (width or height) and extend to the edge of the plot area.

Please, take a look at http://docs.bokeh.org/en/latest/docs/user_guide/annotations.html#spans

So, the code will look like:

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)

With this solution users are allowed to pan and zoom at will. The end of the lines will never show up.




回答2:


The Bokeh documentation on segments and rays indicates the following solution (using ray):

To have an “infinite” ray, that always extends to the edge of the plot, specify 0 for the length.

And indeed, the following code produces an infinite, horizontal line:

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)



回答3:


If you plot two rays from the middle they won't get smaller as you zoom in or out since the length is in pixel. So something like this:

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

But if the user pans in either direction the end of the ray will show up. If you can prevent the user from panning at all (even when they zoom) then this is a little nicer code for a horizontal line.

If the user is able to zoom and pan anywhere they please, there is no good way (as far as I can tell) to get a horizontal line as you describe.




回答4:


In case you are wondering how to use spans in combination with time series, convert your dates to unix timestamps:

start_date = time.mktime(datetime.date(2018, 3, 19).timetuple())*1000
vline = Span(location=start_date,dimension='height', line_color='red',line_width=3)

Or see this link for a full example.



来源:https://stackoverflow.com/questions/28797330/infinite-horizontal-line-in-bokeh

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!