Панорамирование со смещением по x_range - PullRequest
0 голосов
/ 12 апреля 2020

У меня есть два графика, на которых я хочу сравнить что-то на графике 1 с чем-то на графике 2, смещенным вправо по оси X.

Связанное панорамирование работает, когда я связываю оси X: p2 = figure(x_range=p1.x_range, ..., но хочу увидеть другой участок второго сюжета!

enter image description here

Как бы я хотел, чтобы он выглядел, но с связанным панорамированием включено :

enter image description here

Вот мой упрощенный пример кода с моими слабыми попытками прокомментировал:

from numpy import arange, pi, sin

from bokeh.layouts import row
from bokeh.plotting import figure, output_file, show

output_file('custom_linked_ranges.html')

p1_xrange = (-6.5, 6.5)
p2_shift = 10

x1 = arange(-2 * pi, 2 * pi, 0.1)
y1 = sin(x1)
p1 = figure(title='first', x_range=p1_xrange, y_range=(-1.1, 1.1))
p1.circle(x1, y1, color="red")

x2 = arange(p2_shift - 2 * pi, p2_shift + 2 * pi, 0.1)
y2 = sin(x2)
p2 = figure(title="second", x_range=p1.x_range, y_range=(-1.1, 1.1))
p2.circle(x2, y2, color="blue")

# from bokeh.models import CustomJS
# 
# callback = CustomJS(args=dict(xr=p2.x_range), code=F"""
#     console.log(cb_obj)
#     console.log(cb_obj.start)
#     if (cb_obj is changed directly) {{
#         // encode change for p1
#         data['rel_start'] = [cb_obj.start - {p2_shift}]
#         data['rel_end'] = [cb_obj.end - {p2_shift}]
#     }} else {{
#         // cb_obj is changed
#         // decode change for p1
#         xr.start = data['rel_start'] + {p2_shift}
#         xr.end = data['rel_end'] + {p2_shift}
#     }}
# """)
#
# p2.x_range.js_on_change('start', callback)

layout = row(p1, p2)

show(layout)

Я действительно хочу эту функцию, но я недостаточно понимаю структуру Bokeh. Пожалуйста, помогите!

1 Ответ

1 голос
/ 12 апреля 2020
from numpy import arange, pi, sin

from bokeh.layouts import row
from bokeh.models import CustomJS
from bokeh.plotting import figure, output_file, show

output_file('custom_linked_ranges.html')

p1_xrange = (-6.5, 6.5)
p2_shift = 10

x1 = arange(-2 * pi, 2 * pi, 0.1)
y1 = sin(x1)
p1 = figure(title='first', x_range=p1_xrange, y_range=(-1.1, 1.1))
p1.circle(x1, y1, color="red")

x2 = arange(p2_shift - 2 * pi, p2_shift + 2 * pi, 0.1)
y2 = sin(x2)
p2 = figure(title="second", x_range=tuple(i + p2_shift for i in p1_xrange), y_range=(-1.1, 1.1))
p2.circle(x2, y2, color="blue")

code = """\
const start = cb_obj.start + offset;
const end = cb_obj.end + offset;
// Need to update the attributes at the same time.
x_range.setv({start, end});
"""
for attr in ['start', 'end']:
    p1.x_range.js_on_change(attr, CustomJS(args=dict(x_range=p2.x_range,
                                                     offset=p2_shift),
                                           code=code))
    p2.x_range.js_on_change(attr, CustomJS(args=dict(x_range=p1.x_range,
                                                     offset=-p2_shift),
                                           code=code))


layout = row(p1, p2)

show(layout)
...