I am trying to create an interactive scatter plot that will update based on selection of points in another scatter plot.
Based on research and examples provided in the Plotly galleries and on this forum, I have tried to write a selection function to update the second plot from the indices of the data points selected in the first plot. I cannot get the second plot to display and am not certain that my code is correct.
I am using a two separate dataframes - the first (well_df) contains x and y coordinates for some oil wells, and I use these to generate a well location map. The second dataframe (bhp_df) contains time-series pressure data for the same wells as in the first dataframe. I have created a scatter plot which plots the pressure data in a second plot. I want to use the selection tool in the first plot to select a group of wells and I would like the time-series plot to update to show the pressure-time data for the selected wells. I have set the index in both dataframes to be the well name.
This code creates the first plot:
color = well_df['Color']
size = well_df['Cumoil_par_jour']
well = well_df.index
trace1 = go.Scatter(x=well_df['Xcoor'], y=well_df['Ycoor'], opacity=1.0,
name='Wells',mode='markers+text',
text=well, marker=dict(color=color),
textfont=dict(family="raleway", size=8, color="grey"),
textposition="top right")
data=[trace1]
layout=go.Layout(title='Well Locator Map', plot_bgcolor='lightgray',
width=700, height=600)
fig1 = go.Figure(data=data, layout=layout)
The following code is my attempt a creating a function which returns a subset of the second dataframe (dff) based on the indices (well names) selected with the selection tool in the first plot and creates the traces of the pressure-time series data for the second plot:
def selection_fn(trace, points, state):
dff = bhp_df[bhp_df.index.isin([points.point_inds])]
Well_list = dff.Well.unique()
d = {}
data =[]
for well in Well_list:
d[well] = pd.DataFrame()
d[well] = dff[dff.index == well]
trace = go.Scatter(x=d[well].Date, y=d[well].Interp_Sibhp,
name=well, mode='lines+markers')
data.append(trace)
layout = go.Layout(title='SBHP',yaxis=dict(title='Pressure, barg',
showline=True))
fig2 = go.Figure(data=data, layout=layout)
fig2.show()
# Register callback on scatter selection...
fig1.data[0].on_selection(selection_fn)
I don't know how to put this all together so that I end up with two plots side by side or one above the other. Here is how I have put it together:
color = df1['Color']
size = df1['Cumoil_par_jour']
well = df1.index
trace1 = go.Scatter(x=df1['Xcoor'], y=df1['Ycoor'], opacity=1.0,
name='Wells',mode='markers+text',
text=well, marker=dict(color=color),
textfont=dict(family="raleway", size=8, color="grey"),
textposition="top right")
data=[trace1]
layout=go.Layout(title='Well Locator Map', plot_bgcolor='lightgray',
width=700, height=600)
fig1 = go.Figure(data=data, layout=layout)
def selection_fn(trace, points, state):
dff = bhp_df[bhp_df.index.isin([points.point_inds])]
Well_list = dff.Well.unique()
d = {}
data =[]
for well in Well_list:
d[well] = pd.DataFrame()
d[well] = dff[dff.index == well]
trace = go.Scatter(x=d[well].Date, y=d[well].Interp_Sibhp,
name=well,
mode='lines+markers')
data.append(trace)
layout = go.Layout(title='SBHP',yaxis=dict(title='Pressure,
barg',
showline=True))
fig2 = go.Figure(data=data, layout=layout)
fig2.show()
# Register callback on scatter selection...
fig1.data[0].on_selection(selection_fn)
fig1.show()
The only output I get when I run the code is the first plot, but not the second. I would appreciate any advice on how to put this together and let me know where I am going wrong.