Возникли проблемы с использованием js_link для добавления выпадающего селектора в Bokeh - PullRequest
0 голосов
/ 24 апреля 2020

Я пытаюсь внедрить виджеты в свои диаграммы Боке. Первое, что я хотел бы - это выпадающее меню, позволяющее выбрать другие стратегии выбора. Я не могу понять функцию js_link для того, чтобы выбор сделал изменения на графике. Боюсь, что я неправильно настроил диаграмму. Любая помощь с благодарностью.

from bokeh.plotting import figure, output_file, show
from bokeh.models import ColumnDataSource, Div, Select, Slider, TextInput,CustomJSTransform
from bokeh.io import curdoc
from bokeh.transform import transform
from bokeh.layouts import gridplot, column
import matplotlib
import matplotlib.pyplot as plt
import numpy as np


strike1 = 20 #Long Call
strike2 = 33 #Short Call
strike3 = 30 #Long Put
strike4 = 60 #Short Put
premium1 = 0.5
premium2 = 1.6
premium3 = 2.1
premium4 = 1.5
price = np.arange(15,25,0.01)
contracts = 1
symbol = 'TSLA'
option = ['Long Call', 'Long Put', 'Short Call', 'Short Put', 'Bull Call Spread', 'Bear Put Spread', 'Straddle',
          'Butterfly Spread', 'Box Spread', 'Iron Condor']


def long_call(price, strike1, premium1, contracts):
    P = []
    for i in price:
        P.append((max(i - strike1, 0) - premium1) * (contracts * 100))
    return np.array(P)

def long_put(price, strike1, premium1, contracts):
    P = []
    for i in price:
        P.append((max(strike1 - i, 0) - premium1) * (contracts * 100))
    return np.array(P)

def straddle(price, strike1, premium1, premium2, contracts):
    P1 = long_call(price, strike1, premium1, contracts)
    P2 = long_put(price, strike1, premium2, contracts)
    return np.array(P1+P2)

def bull_call_spread(price, strike1, strike2, premium1, premium2, contracts):
    P1 = long_call(price, strike1, premium1, contracts)
    P2 = short_call(price,strike2, premium2, contracts)
    return np.array(P1+P2)

# Graph Items
x= price
y= long_call(price, strike1, premium1, contracts)
ds = ColumnDataSource(dict(x=price,
                           y=straddle(price, strike1, premium1, premium2, contracts)))

strategy = Select(title="Strategy", value="option", options=option)
strike = TextInput(title="Strike")


# create a new plot with a title and axis labels
p = figure(title="Option Payoff", x_axis_label='Underlying Price ($)', y_axis_label='Profit/Loss ($)')

# add a line renderer with legend and line thickness
p.line('x', 'y', source=ds, line_width=2)
p.varea(x='x', y1=transform('y', CustomJSTransform(v_func="return xs.map(x => x > 0 ? x : 0)")),
        y2=0, source=ds, color='#3cb371', fill_alpha=0.5)
p.varea(x='x', y1=transform('y', CustomJSTransform(v_func="return xs.map(x => x < 0 ? x : 0)")),
        y2=0, source=ds, color='#ff6347', fill_alpha=0.5)

select = Select(title="Strategy", value="Long Call", options=option)
select.js_link('options', p, 'y')

# initial load of the data

show(column(p,select,strike_input))

1 Ответ

0 голосов
/ 24 апреля 2020

Все, что js_link делает, это устанавливает атрибут второй модели равным значению атрибута первой модели всякий раз, когда он изменяется. Вот и все.

select.js_link('options', p, 'y') в основном говорит "Выполнить p.y = select.options всякий раз, когда select.options изменяется". p является экземпляром Figure и не имеет свойства y.

Из вашего вопроса и вашего кода неясно, что вы хотите. Но вы, вероятно, хотите наблюдать за изменением свойства select.value вместо select.options. И кажется, что вам нужно изменить сами данные, то есть вам придется либо использовать CustomJS и переписать все функции манипулирования данными в JS, либо использовать bokeh serve, чтобы иметь возможность запускать код Python в ответ до select.value изменения. Или, может быть, вы могли бы предварительно вычислить все необходимые данные, чтобы вам не нужно было запускать код Python в ответ на действия пользователя, но вам все равно нужно было написать код для CustomJS.

...