2015-11-18 23 views
6

özel javascript uygulanması:Bokeh: Ben Bokeh içinde bu iki örneği birleştirmek çalışıyorum bir görüntü arsa

http://bokeh.pydata.org/en/latest/docs/gallery/image.html http://bokeh.pydata.org/en/latest/docs/user_guide/interaction/callbacks.html#customjs-for-widgets

fikri basit görünüyor. Ben ilk linkte gösterilen görüntüyü çizmek istiyorum, sonra interaktif kaydırma çubuğunu kullanarak sinüs fonksiyonunun frekansı değişir: sağ

import numpy as np 

from bokeh.plotting import figure, show, output_file 
from bokeh.models import CustomJS, ColumnDataSource, Slider 
from bokeh.io import vform 


N = 10 

x = np.linspace(0, 10, N) 
y = np.linspace(0, 10, N) 
xx, yy = np.meshgrid(x, y) 
d = np.sin(xx)*np.cos(yy) 

output_file("image.html", title="image.py example") 

source = ColumnDataSource(data={'d': d, 'x': x, 'y': y}) 

p = figure(x_range=[0, 10], y_range=[0, 10]) 
p.image([source.data['d']], x=[0], y=[0], dw=[10], dh=[10], palette="Spectral11") 

callback = CustomJS(args=dict(source=source), code=""" 
     var data = source.get('data'); 
     var f = cb_obj.get('value') 
     x = data['x'] 
     y = data['y'] 
     d = data['d'] 
     for (i = 0; i < x.length; i++) { 
      for (i = 0; i < x.length; i++){ 
       d[i][j] = Math.sin(f*x[i])*Math.cos(y[j]) 
     } 
     source.trigger('change'); 
    """) 

slider = Slider(start=0.1, end=4, value=1, step=.1, title="angular frequency", callback=callback) 

layout = vform(slider, p) 

show(layout) 

grafik araziler, ancak görüntü asla güncellemeleri. neredeyse kesin Sorun görüntüyü komplo am nasıl var:

p.image([source.data['d']], x=[0], y=[0], dw=[10], dh=[10], palette="Spectral11") 

ben sanmıyorum düzgün bir kaynak nesnesine bir arsa takmak nasıl. Sadece bir dizide geçiyorum, kaynak değiştiğinde çizimin neden güncellenmediğini açıklıyor, ancak görüntü işlevi için doğru yöntemin ne olduğundan emin değilim. Açıklamayı düzgün olarak değiştirmezseniz, bu ifadeyi değiştirmezseniz, doğru şekilde çizim yapmayacaktır. Bunun bir sözdizimi sorunu veya daha derin bir sorun olup olmadığından emin değilim. Herhangi bir işaretçi takdir edilecektir. Şimdiden teşekkürler.

cevap

8

Birkaç gün için benzer bir problemle uğraşıyordum. Sonunda çalıştım. İlk olarak, ColumnDataSource işlevindeki parantez [] 'ye dikkat edin. Veriler çoklu görüntülere izin verir. Dolayısıyla, geri arama işlevinin içinde, bir görüntü için veri almak için [0] kullanmalısınız. Ayrıca görüntü için kaynakta 'x' ve 'y' kullanımı x = [0] ve y [0] konumunun konumu ile çakışır, dolayısıyla xx ve yy kullanılır. Kodun bir örneğinden color_sliders.py tobyhodges tarafından borç aldığımdan bahsetmek istiyorum: kaydırıcı bilgilerini önceden tanımlanmış bir geri çağırma işlevine itmenin bir yolu. İşte kod:

import numpy as np 
from bokeh.plotting import figure, show, output_file 
from bokeh.models import CustomJS, ColumnDataSource, Slider 
from bokeh.io import vform 

N = 100 

x = np.linspace(0, 10, N) 
y = np.linspace(0, 10, N) 
xx, yy = np.meshgrid(x, y) 
d = np.sin(xx)*np.cos(yy) 

output_file("image.html", title="image.py example") 

source = ColumnDataSource(data={'d': [d], 'xx': [x], 'yy': [y]}) 

p = figure(x_range=[0, 10], y_range=[0, 10]) 
p.image(image="d", x=[0], y=[0], dw=[10], dh=[10], palette="Spectral11",source=source) 

callback = CustomJS(args=dict(source=source), code=""" 
     var xx = source.get('data')['xx'][0]; 
     var yy = source.get('data')['yy'][0]; 
     var d = source.get('data')['d'][0]; 
     var f = slider.get('value'); 
     for (var i = 0; i < xx.length; i++) { 
      for (var j = 0; j < yy.length; j++){ 
       d[i][j] = Math.sin(f * xx[i]) * Math.cos(yy[j]); 
      } 
     } 
     source.trigger('change'); 
    """) 

slider = Slider(start=0.1, end=4, value=1, step=.1, title="angular frequency", callback=callback) 
callback.args['slider'] = slider 
layout = vform(slider, p) 
show(layout) 

bokeh şöyle Bu kodu değiştirdiniz (Sadece 0.12.3 edilir yüklemiş sürümü) en son sürümünde kullanımdan kaldırma uyarılarını kaçının. Bu kodda, görüntü için veri kaynağı kullanmıyorum. İçerisinde CustomJS "Im" görüntü tanıtıcısını geçiriyorum ve veri kaynağını im.data_source olarak aldım. bokeh sürümü 0.12.4 için

import numpy as np 
import bokeh 
import bokeh.plotting 

N = 100 

x = np.linspace(0, 10, N) 
y = np.linspace(0, 10, N) 
xx, yy = np.meshgrid(x, y) 
d = np.sin(xx)*np.cos(yy) 

source = bokeh.models.ColumnDataSource(data={'x': [x], 'y': [y]}) 

p = bokeh.plotting.figure(x_range=[0, 10], y_range=[0, 10]) 
im = p.image(image=[d], x=[0], y=[0], dw=[10], dh=[10], palette="Spectral11") 

callback = bokeh.models.CustomJS(args=dict(source=source,im=im), code=""" 
     var x = source.data['x'][0]; 
     var y = source.data['y'][0]; 
     var image_source = im.data_source; 
     var d = image_source.data['image'][0]; 
     var f = slider.value; 
     for (var i = 0; i < x.length; i++) { 
      for (var j = 0; j < y.length; j++){ 
       d[i][j] = Math.sin(f * x[i]) * Math.cos(f * y[j]); 
      } 
     } 
     image_source.trigger('change'); 
    """) 

slider = bokeh.models.Slider(start=0.1, end=4, value=1, step=.1, 
          title="angular frequency", callback=callback) 
callback.args['slider'] = slider 
layout = bokeh.models.layouts.Column(slider, p) 

bokeh.io.output_file("image.html", title="image.py example") 
bokeh.io.save(layout) 

Güncelleme:

Değişiklikler: çıktı şimdi Jupyter dizüstü içindir. Html sayfasını elde etmek için sadece önceki sürümleri takip edin. Bu bokeh sürümünde yeni: JavaScript dizisi artık 1D dizisidir.

import numpy as np 
import bokeh 
import bokeh.plotting 

N = 100 

x = np.linspace(0, 10, N) 
y = np.linspace(0, 10, N) 
xx, yy = np.meshgrid(x, y) 
d = np.sin(xx)*np.cos(yy) 

source = bokeh.models.ColumnDataSource(data={'x': [x], 'y': [y]}) 

p = bokeh.plotting.figure(plot_width=300, plot_height=300,x_range=[0, 10], y_range=[0, 10]) 
im = p.image(image=[d], x=[0], y=[0], dw=[10], dh=[10], palette="Spectral11") 

callback = bokeh.models.CustomJS(args=dict(source=source,im=im), code=""" 
     var x = source.data['x'][0]; 
     var y = source.data['y'][0]; 
     var image_source = im.data_source; 
     var d = image_source.data['image'][0]; 
     var f = slider.value; 
     for (var j = 0; j < y.length; j++){ 
      for (var i = 0; i < x.length; i++) { 
       d[j*y.length + i] = Math.sin(f * x[i]) * Math.cos(f * y[j]); 
      } 
     } 
     image_source.trigger('change'); 
    """) 

slider = bokeh.models.Slider(start=0.1, end=4, value=1, step=.1, 
          title="angular frequency",callback=callback) 
callback.args['slider'] = slider 
layout = bokeh.models.layouts.Row(p,slider) 

bokeh.io.output_notebook() 
bokeh.io.show(layout) 

enter image description here

+0

Erkeksin. Teşekkürler arkadaşım. Gerçekten onu takdir ederim. Yaptığım hataları görmek, veri kaynakları ile neler olup bittiğini daha iyi anlamamı sağlıyor. –

İlgili konular