问题描述
我有一个一维 numpy 数组,例如[1,6,3,2,1,4,1],我已经能够使用散景库。
我希望能够使用图形交互修改数组。
理想情况下,我希望能够一次移动 1 个值。
任何想法将不胜感激:)
import numpy as np
import pandas as pd
from bokeh.models import ColumnDataSource,Grid,Linearaxis,Plot,Quad,Range1d,HoverTool,Panel,Tabs,Legend,LegendItem,FixedTicker,NumeralTickFormatter,SingleIntervalTicker
from bokeh.plotting import figure
from bokeh.embed import components
from bokeh.io import curdoc,show
#-------------------------------------------------------------------------------------------------
# Create Data
#-------------------------------------------------------------------------------------------------
Values= np.random.randint(0,6000,800)
def Values_to_Bins(Values,Bin_size): #takes in a numpy array of values,and the Bin size
Min_Value = np.amin(Values)
Max_Value =np.amax(Values)
bins = np.arange(Min_Value,Max_Value + 2 * (Bin_size),Bin_size) # Define bin edges
hist_array,edges = np.histogram(Values,bins=bins) # Create 2 arrays,hist_array represents the bin counts,edges is the bin edges
return hist_array,edges #Returns the histogram array,and edges
# -------------------------------------------------------------------------------------------------
# STEP X: Create bokeh Histogram Plots
# -------------------------------------------------------------------------------------------------
hist_array,edges = Values_to_Bins(Values,15)
# Create a Pandas Dataframe
bokeh_Bins = pd.DataFrame({'Values': hist_array,'left': edges[:-1],'right': edges[1:]})
Max_Initial_Bin = bokeh_Bins['Values'].max()
# Create a column showing the extent of each interval
bokeh_Bins['Bin_interval'] = ['%d to %d ms' % (left,right) for left,right in
zip(bokeh_Bins['left'],bokeh_Bins['right'])]
tick_vals = np.arange(Max_Initial_Bin + 1)
# Convert dataframe to column data source
src1 = ColumnDataSource(bokeh_Bins)
plot = figure(y_range=Range1d(start=0,end=Max_Initial_Bin),sizing_mode="scale_width",width=3000,height=600,title="Want to create interactive Histogram data",x_axis_label="Time (ms)",y_axis_label="Number of occurances")
plot.yaxis.ticker = FixedTicker(ticks=list(tick_vals))
plot.quad(bottom=0,top='Values',left='left',right='right',source=src1,fill_color="#939393",line_color='black',fill_alpha=0.5,hover_fill_alpha=1.0,hover_fill_color='#00E400')
# Add hover tool for when mouse is over data
hover1 = HoverTool(tooltips=[('Timeframe','@Bin_interval'),('Count','@Values')])
plot.add_tools(hover1)
original_script,original_div = components(plot)
show(plot)
解决方法
为了使用 Boken
进行交互修改,您可以添加一个 Widgets
,如 sliders
和其他,其中使用这些小部件所做的任何修改都会触发相应的回调函数。您可以在以下链接中找到很好的信息:
https://docs.bokeh.org/en/latest/docs/user_guide/interaction/widgets.html
在该链接中,您将找到大量 Python 示例。
当然,欢迎其他支持,我会给予。
,直方图中的每个条形对应一组数据点。你需要一些规则(随机选择一个?最小的?最大的?)来移动。然后当你将它移动到另一个 bin 时,你还需要选择设置它的值(bin 中心?左边还是右边?在 bin 中均匀的某个地方)。
一旦您做出了这些选择,那么在实现以下伪代码的地方实现回调应该不会太难。
[bin_edges,bin_counts,data_map] = histogram(data)
[bin,y] = picked_bin() # This returns the value of your 1st mouse click
[newbin,newy] = set_bin() # This returns the value of your 2nd mouse click
possible_points = bin_edges[data_map] == x
old_datum_ind = pick_one(data,possible_points)
data[old_datum_ind] = assign_new_value(newx)
关键信息是data_map
,它与数据的长度相同,但它是将数据中的每个数据映射到一个bin的索引。这让您可以轻松找出与每个 bin 对应的数据点。