I am trying to showcase a scatter plot as well as the data for the the plot side by side in jupyter. I wish to add a plotly button (dropdown) that will show the filtered data as well as the corresponding scatter plot. Is this possible WITHOUT USING ipywidgets, using plotly dropdowns?
I was able to build two separate plots for data and scatter plot with dropdowns but cannot combine them together. Following is the code I tried. Here the dropdown only interacts with the table, the scatter plot is not updating.
import plotly.express as px
import plotly.graph_objects as go
import numpy as np
import pandas as pd
df = px.data.iris()
species = sorted(set(df['species']))
#fig=go.Figure()
default_species = "setosa"
df_default = df[df['species']==default_species]
fig = make_subplots(
rows=1, cols=2,
shared_xaxes=True,
horizontal_spacing=0.02,
specs=[[{"type": "scatter"},{"type": "table"}]]
)
fig.add_trace(
go.Scatter(
x=df_default["sepal_length"],
y=df_default["sepal_width"],
mode="markers"
),
row=1, col=1
)
fig.add_trace(
go.Table(
header=dict(
values=["sepal<br>length","sepal<br>length","petal<br>length","petal<br>width","species","species<br>id"],
font=dict(size=10),
align="left"
),
cells=dict(
values=[df_default[k].tolist() for k in df_default.columns],
align = "left")
),
row=1, col=2
)
buttons = []
for s in species:
s_data = df[df['species']==s]
buttons.append(dict(
method='restyle',
label=s,
visible=True,
args=[
{'values':[["sepal<br>length","sepal<br>length","petal<br>length","petal<br>width","species","species<br>id"]],
'cells':[dict(values=[s_data[k].tolist() for k in s_data.columns],align = "left")]},
{'y':[s_data["sepal_width"]],
'x':[s_data['sepal_length']],
'type':'scatter',
'mode':'markers'}
]
))
#fig.update_layout(width=1500, height=500)
# some adjustments to the updatemenus
updatemenu = []
your_menu = dict()
updatemenu.append(your_menu)
updatemenu[0]['buttons'] = buttons
updatemenu[0]['direction'] = 'down'
updatemenu[0]['showactive'] = True
updatemenu[0]['active'] = species.index(default_species)
updatemenu[0]['x'] = 0
updatemenu[0]['xanchor'] = 'left'
updatemenu[0]['y'] = 1.2
updatemenu[0]['yanchor'] = 'top'
# add dropdown menus to the figure
fig.update_layout(showlegend=False,
updatemenus=updatemenu,
xaxis_title="Sepal_Length",
yaxis_title="Sepal_Width"
)
fig.show()
I do not want to use ipywidgets.
The code that worked for me: Editing hope it helps some one
## Create Combination of Scatter Plot and Plotly Tables with interactive Static HTML
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import numpy as np
import pandas as pd
df = px.data.iris()
species_list = sorted(set(df['species']))
# --- function ---
def make_multi_plot(df1, item_list):
fig = make_subplots(rows=1,
cols=2,
#shared_xaxes=True,
#vertical_spacing=0.2,
specs = [[{}, {"type": "table"}]]
)
for item_id in item_list:
#print('item_id:', item_id)
trace1 = go.Scatter(
x=df1.loc[df1.species.isin([item_id])].sepal_length,
y=df1.loc[df1.species.isin([item_id])].sepal_width,
mode='markers',
name = str(item_id)
)
fig.append_trace(trace1, 1, 1)
trace2 = go.Table(
columnorder = [1,2,3,4,5,6],
columnwidth = [2,2,2,2,4,2],
header=dict(
values = ["sepal<br>length","sepal<br>length","petal<br>length","petal<br>width","species","species<br>id"],
font = dict(size=10),
align = "left"
),
cells = dict(
values = [df1[df1.species.isin([item_id])][k].tolist() for k in df1[df1.species.isin([item_id])].columns[:]],
align = "left"
)
)
fig.append_trace(trace2,1,2)
Ld = len(fig.data)
#print(Ld)
Lc = len(item_list)
for k in range(2, Ld):
fig.update_traces(visible=False, selector=k)
def create_layout_button(k, item_id):
#print(k, item_id)
visibility = [False]*2*Lc
for tr in [2*k, 2*k+1]:
visibility[tr] = True
#print(visibility)
return dict(label = item_id,
method = 'restyle',
args = [{'visible': visibility,
'title': item_id
}])
#updatemenu[0]['x'] = 0
#updatemenu[0]['xanchor'] = 'left'
#updatemenu[0]['y'] = 1.2
#updatemenu[0]['yanchor'] = 'top'
fig.update_layout(
updatemenus=[go.layout.Updatemenu(
active=0,
buttons=[create_layout_button(k, item_id) for k, item_id in enumerate(item_list)],
x=0.5,
y=1.3
)],
#title='Model Raporu',
#template='plotly_dark',
#height=800
xaxis_title="Sepal_Length",
yaxis_title="Sepal_Width"
)
fig.show()
# --- main ---
make_multi_plot(df1=df, item_list=species_list)