在Bokeh中滑块的箭头图

时间:2016-12-21 09:39:49

标签: python html matplotlib

我开发了一个完全正常的代码,但现在我想把它展示给我的教授,而不必随身携带我的电脑。代码是:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button, RadioButtons

a = 0.5

X, Y = np.mgrid[0:1.05:0.025, 0:1.05:0.025]
varX = #Some equation with X, Y and a (as a parameter)
varY = #Some other equation

U = varX-X
V = varY-Y

length = np.sqrt(U**2 + V**2)

fig, ax = plt.subplots()
Q = plt.quiver(X, Y, varX-X, varY-Y,
                color='r',
                scale=3*(2 ** .5), units='y')

plt.subplots_adjust(left=0.25, bottom=0.25)

plt.axis([0, 1, 0, 1])

axcolor = 'lightgoldenrodyellow'
axa = plt.axes([0.25, 0.10, 0.65, 0.03], axisbg=axcolor)

sa = Slider(axa, 'Alfa', 0, 1, valinit=a)

def update(val):
    a = sa.val

    varX = #Same equation as before
    varY = #Same equation

    Q.set_UVC(varX - X, varY - Y)
    fig.canvas.draw_idle()

sa.on_changed(update)


resetax = plt.axes([0.8, 0.025, 0.1, 0.04])
button = Button(resetax, 'Reset', color=axcolor, hovercolor='0.975')

def reset(event):
    sa.reset()
button.on_clicked(reset)

plt.show()

正如我所说,这段代码就像一个魅力,但我怎么能保存"结果?我曾经考虑制作一个html-js版本,但是不能为它制作一个类似Bokeh的版本而且mpld3似乎不支持滑块...

提前致谢,

Javirk

1 个答案:

答案 0 :(得分:1)

最后我可以自己解决这个问题。我不得不使用“segment”而不是“multi_line”,因为我不想设置服务器。代码:

from __future__ import division

import numpy as np

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

#Declaration of variables 

xx = np.linspace(0, 1, 50)
yy = np.linspace(0, 1, 50)

Y, X = np.meshgrid(xx, yy)

x0 = X[::2, ::2].flatten()
y0 = Y[::2, ::2].flatten()

#Equations and so, result: x1,y1 with same dimensions as x0,y0
#x1,y1 are the coordinates of the final point of the segment

source = ColumnDataSource(data=dict(x0=x0, y0=y0, x1=x1, y1=y1))

#Plot
plot = figure(x_range=(0, 1), y_range=(0, 1), x_axis_label='H', y_axis_label='C',
              title="Retrato de fases. Modelo simplificado")
plot.segment('x0', 'y0', 'x1', 'y1', source=source, line_width=1)

#JS function that activates when slider value is changed
callback = CustomJS(args=dict(source=source), code="""
    var data = source.data;
    var alpha = alpha.value;

    x0 = data['x0'];
    y0 = data['y0'];
    x1 = data['x1'];
    y1 = data['y1'];

    for (i = 0; i < x0.length; i++) {
        #Same equations as before, but written in JS
    }
    source.trigger('change');
""")

#Set up all the sliders
alfa_slider = Slider(start=0, end=1, value=alpha, step=.01, title="Alpha", callback=callback)
callback.args["alpha"] = alpha_slider

output_file("slider.html", title="Phase Portrait")

layout = row(
    plot,
    widgetbox(alpha_slider),
)
show(layout)