Reputation: 3053
In this example, they plot everything in a single go.Scatter
tracer and then they can use the selection_fn
to get the information for the selected points.
I want to do similar thing with my dataset with consists of 3 clusters. In order to make the clusters easier to be seen, I use one tracer for one class. Therefore, I try to modify the example code to adapt to my dataset as shown below.
import plotly.plotly as py
import plotly.graph_objs as go
from plotly.tools import set_credentials_file
import plotly.offline as py
import pandas as pd
import numpy as np
from ipywidgets import interactive, HBox, VBox
from sklearn.datasets import make_blobs
X, y = make_blobs(30,random_state=101)
py.init_notebook_mode()
f = go.FigureWidget([go.Scatter(y = X[y==0][:,1], x = X[y==0][:,0], mode = 'markers'),
go.Scatter(y = X[y==1][:,1], x = X[y==1][:,0], mode = 'markers'),
go.Scatter(y = X[y==2][:,1], x = X[y==2][:,0], mode = 'markers')])
scatter = f.data[0]
N = len(X)
# Create a table FigureWidget that updates on selection from points in the scatter plot of f
t = go.FigureWidget([go.Table(
header=dict(values=['x','y','class'],
fill = dict(color='#C2D4FF'),
align = ['left'] * 5),
cells=dict(values=[X[:,0], X[:,1], y],
fill = dict(color='#F5F8FF'),
align = ['left'] * 5))])
def selection_fn(trace,points,selector):
print(points.point_inds)
t.data[0].cells.values = [X[points.point_inds,0], X[points.point_inds,1], y[points.point_inds]]
scatter.on_selection(selection_fn)
# Put everything together
VBox((HBox(),f,t))
When selecting two data points from trace 0
, it does return 2 information to me, yet it's wrong.
When selecting data points from tracer 1 and 2, it doesn't even return the information
After a brief debugging, I notices that there is mismatch in the index for each tracer and the complete dataset. This code can return the index from tracer 0 only, however, when it passes the index to the full dataset, it gives you the mis-matached information for the points. When selecting points from tracer 1 and 2, it can't even return the index, thus no information can be extracted.
Although I understand the problem, I don't know how to modify the code since I am still new to plotly.
Upvotes: 3
Views: 1229
Reputation: 3053
After trying it for several days, I have figured out a hack to achieve it. (Maybe someone can still provide a better way?)
The trick is to create 3 lists for each of the column in the table, and the append the data of the selected points to the list, and update the table in the end.
Here's the complete code.
X, y = make_blobs(30,random_state=101)
py.init_notebook_mode()
f = go.FigureWidget([go.Scatter(y = X[y==0][:,1], x = X[y==0][:,0], text=y[y==0], mode = 'markers', name='class 0'),
go.Scatter(y = X[y==1][:,1], x = X[y==1][:,0], text=y[y==1], mode = 'markers', name='class 1'),
go.Scatter(y = X[y==2][:,1], x = X[y==2][:,0], text=y[y==2], mode = 'markers', name='class 2')])
# Create a table FigureWidget that updates on selection from points in the scatter plot of f
t = go.FigureWidget([go.Table(
header=dict(values=['x','y', 'class'],
fill = dict(color='#C2D4FF'),
align = ['left'] * 5),
cells=dict(values=[X[:,0], X[:,1], y],
fill = dict(color='#F5F8FF'),
align = ['left'] * 5))])
# def data_append(trace,points,selector):
# X1 = []
# X2 = []
# c = []
X1 = []
X2 = []
data_cluster = []
num_called = 0
def selection_fn(trace,points,selector):
global num_called
global X1, X2, data_cluster
if num_called == 3: # number of scatters
num_called = 0
X1 = []
X2 = []
data_cluster = []
X1.extend(trace['x'][points.point_inds])
X2.extend(trace['y'][points.point_inds])
data_cluster.extend(trace['text'][points.point_inds])
t.data[0].cells.values = [X1, X2,data_cluster]
num_called +=1
for scatter in f.data:
scatter.on_selection(selection_fn)
# Put everything together
VBox((HBox(),f,t))
As you can see, the table return exactly the information for the three selected data points.
Upvotes: 2