V3 de la 3D App

This commit is contained in:
2024-05-24 14:58:18 +02:00
parent 8ccc6fd322
commit 560c6fad0e
6 changed files with 769 additions and 260 deletions

View File

@ -10,3 +10,9 @@
* Correction des dépendances obselètes
* Ajustement des sliders avec des valeurs commençant par 1 et non 0
* Changement du thème en dark
## V3
* Ajout d'un menu pour naviguer entre les pages
* Ajout des popups pour afficher les graphiques en plein écran
* Ajout de la page avec les filtres pour la A-scan

View File

@ -1,196 +1,14 @@
import dash
from dash import dcc, html
from dash.dependencies import Input, Output
import plotly.graph_objects as go
import numpy as np
from util import *
import dash_bootstrap_components as dbc
import plotly.express as px
import plotly.io as pio
# on définit le dossier et les fichiers à lire
dossier = "Dataset/Shear_transform"
fichiers_selectionnes = [
"Shear_x001-x101_y{:03d}_Rot00_transform.csv".format(i) for i in range(10, 14)
]
# dossier = "Dataset/Shear_Wave_Rot00_CSV_Data"
# fichiers_selectionnes = ['Shear_x001-x101_y{:03d}_Rot00.csv'.format(i) for i in range(10, 62)]
# on lit les fichiers et on les met dans un tableau
pre_volume = np.array(lire_fichier_csv(dossier, fichiers_selectionnes))
volume = pre_volume[:, ::32, :]
dim_x, dim_y, dim_z = volume.shape
X, Y, Z = np.mgrid[0:dim_x, 0:dim_y, 0:dim_z]
# on défini le thème de l'application
pio.templates.default = "plotly_dark"
# on crée le plot 3D
fig = go.Figure(
data=go.Volume(
x=X.flatten(),
y=Y.flatten(),
z=Z.flatten(),
value=volume.flatten(),
isomin=5000,
isomax=volume.max(),
opacity=0.1, # needs to be small to see through all surfaces
surface_count=20, # needs to be a large number for good volume rendering
colorscale="Jet"
)
)
# on défini les configurations des plots
config3DPlot = {
"toImageButtonOptions": {
"format": "svg", # one of png, svg, jpeg, webp
"filename": "3D-Plot",
"height": 1000,
"width": 1400,
"scale": 1, # Multiply title/legend/axis/canvas sizes by this factor
},
"displaylogo": False
}
configAScan = {
"toImageButtonOptions": {
"format": "svg", # one of png, svg, jpeg, webp
"filename": "A-Scan",
"height": 1000,
"width": 1400,
"scale": 1, # Multiply title/legend/axis/canvas sizes by this factor
},
"displaylogo": False
}
configBScanXY = {
"toImageButtonOptions": {
"format": "svg", # one of png, svg, jpeg, webp
"filename": "B-Scan XY",
"height": 1000,
"width": 1400,
"scale": 1, # Multiply title/legend/axis/canvas sizes by this factor
},
"displaylogo": False
}
configBScanZX = {
"toImageButtonOptions": {
"format": "svg", # one of png, svg, jpeg, webp
"filename": "B-Scan ZX",
"height": 1000,
"width": 1400,
"scale": 1, # Multiply title/legend/axis/canvas sizes by this factor
},
"displaylogo": False
}
# on crée l'application
app = dash.Dash(__name__, external_stylesheets=[dbc.themes.DARKLY])
app = dash.Dash(__name__, external_stylesheets=[dbc.themes.DARKLY, dbc.icons.BOOTSTRAP], use_pages=True)
# on crée les cartes
# carte pour le plot 3D
mesh_card = dbc.Card(
[
dbc.CardBody(
[
dcc.Graph(id="3dplot", figure=fig, config=config3DPlot, style={"height": "411px", "marginBottom": "15px"}), # 'fig' is your 3D plotly figure
dcc.Slider(
id="iso-slider",
min=volume.min(),
max=volume.max() / 2,
value=volume.min(),
marks={
str(i): str(i)
for i in range(
int(volume.min()),
int(volume.max() / 2) + 1,
int((volume.max() / 2 - volume.min()) / 10),
)
},
step=1,
),
dcc.RangeSlider(
id="y-slider",
min=0,
max=dim_y,
value=[0, dim_y / 2],
marks={
str(i): str(i)
for i in range(0, int(dim_y) + 1, max(1, int(dim_y / 20)))
},
step=1,
),
]
)
]
)
print('Reloading...')
# carte pour le A-scan
Ascan_card = dbc.Card(
[
dbc.CardBody(
[
dcc.Graph(id="heatmap-ascan", config=configAScan, style={"marginBottom": "15px"}), # 'fig' is your 2D plotly figure
dcc.Slider(
id="layer-slider-ascan",
min=1,
max=dim_x,
value=1,
step=1,
marks={
str(i): str(i) for i in range(1, dim_x + 1, max(1, int(dim_x / 20)))
},
),
]
)
]
)
# carte pour le B-scan XY
Bscan_card_xy = dbc.Card(
[
dbc.CardBody(
[
dcc.Graph(id="heatmap-bscan-xy", config=configBScanXY, style={"marginBottom": "15px"}), # 'fig' is your 2D plotly figure
dcc.Slider(
id="layer-slider-bscan-xy",
min=1,
max=dim_x,
value=1,
step=1,
marks={
str(i): str(i) for i in range(1, dim_x + 1, max(1, int(dim_x / 20)))
},
),
]
)
]
)
# carte pour le B-scan ZX
Bscan_card_zx = dbc.Card(
[
dbc.CardBody(
[
dcc.Graph(id="heatmap-bscan-zx", config=configBScanZX, style={"marginBottom": "15px"}), # 'fig' is your 2D plotly figure
dcc.Slider(
id="layer-slider-bscan-zx",
min=1,
max=dim_z - 1,
value=1,
step=1,
marks={
str(i): str(i) for i in range(1, dim_z + 1, max(1, int(dim_z / 20)))
},
),
]
)
]
)
# on lit le fichier modal.md pour le tuto
with open("assets/modal.md", "r") as f:
@ -224,6 +42,32 @@ button_howto = dbc.Button(
style={"textTransform": "none", "marginRight": "10px"},
)
navmenu = html.Div(
dbc.Offcanvas(
dbc.ListGroup(
[
dbc.Nav(
[
dbc.NavLink(
html.Div(page["name"], className="ms-2"),
href=page["path"],
active="exact",
)
for page in dash.page_registry.values()
if not page["path"].startswith("/fullscreen")
],
vertical=True,
pills=True,
className="bg-dark",
)
]
),
id="offcanvas-menu",
title="3D App",
is_open=False,
),
)
# on défini la navbar
nav_bar = dbc.Navbar(
dbc.Container(
@ -234,15 +78,27 @@ nav_bar = dbc.Navbar(
dbc.Row(
[
dbc.Col(
html.A(
html.Img(
src=app.get_asset_url(
"logo_IJL couleur.png"
),
height="100px",
[
dbc.Button(
html.Span(className="navbar-toggler-icon"),
outline=True,
color="secondary",
id="navbar-toggler",
style={
"marginRight": "10px",
"marginLeft": "10px",
},
),
href="https://ijl.univ-lorraine.fr/",
),
html.A(
html.Img(
src=app.get_asset_url(
"logo_IJL couleur.png"
),
height="64px",
),
href="https://ijl.univ-lorraine.fr/",
),
],
style={"width": "min-content"},
),
dbc.Col(
@ -263,7 +119,6 @@ nav_bar = dbc.Navbar(
),
dbc.Col(
[
dbc.NavbarToggler(id="navbar-toggler"),
dbc.Collapse(
dbc.Nav(
[dbc.NavItem(button_howto), dbc.NavItem(button_gh)],
@ -273,91 +128,29 @@ nav_bar = dbc.Navbar(
id="navbar-collapse",
navbar=True,
),
], align="right"
],
align="right",
),
modal_overlay,
navmenu,
],
align="center",
style={"width": "100%"},
),
],
fluid=True,
style={"--bs-gutter-x": "0"}
style={"--bs-gutter-x": "0"},
),
dark=True,
)
# on défini le layout de l'application
app.layout = dbc.Container(
[
nav_bar,
dbc.Row([dbc.Col(Ascan_card, width=6), dbc.Col(mesh_card, width=6)], style={"margin": "8px"}),
dbc.Row([dbc.Col(Bscan_card_xy, width=6), dbc.Col(Bscan_card_zx, width=6)], style={"margin": "8px"})
],
[nav_bar, dash.page_container],
fluid=True,
)
# on défini les callbacks
# callback pour le plot 3D
@app.callback(
Output("3dplot", "figure"),
[Input("iso-slider", "value"), Input("y-slider", "value")],
)
def update_3dplot(iso_value, y_values):
y_min, y_max = y_values
selected_volume = volume[0:dim_x, int(y_min) : int(y_max), 0:dim_z]
X, Y, Z = np.mgrid[
0 : selected_volume.shape[0],
0 : selected_volume.shape[1],
0 : selected_volume.shape[2],
]
fig = go.Figure(
data=go.Volume(
x=X.flatten(),
y=Y.flatten(),
z=Z.flatten(),
value=selected_volume.flatten(),
isomin=iso_value,
isomax=selected_volume.max(),
opacity=0.1,
surface_count=20,
colorscale="Jet",
)
)
return fig
# callback pour le A-scan
@app.callback(Output("heatmap-ascan", "figure"), [Input("layer-slider-ascan", "value")])
def update_heatmap_ascan(layer):
fig = px.line(y=volume[layer - 1, :, 5], title="A-scan")
return fig
# callback pour les B-scan XY
@app.callback(
Output("heatmap-bscan-xy", "figure"), [Input("layer-slider-bscan-xy", "value")]
)
def update_heatmap_bscan_xy(layer):
fig = px.imshow(
volume[layer - 1, :, :],
color_continuous_scale="Jet",
aspect="auto",
title="B-scan XY",
)
return fig
# callback pour les B-scan ZX
@app.callback(
Output("heatmap-bscan-zx", "figure"), [Input("layer-slider-bscan-zx", "value")]
)
def update_heatmap_bscan_zx(layer):
fig = go.Figure(data=go.Heatmap(z=volume[:, :, layer], colorscale="Jet"))
return fig
# callback pour le modal
@app.callback(
Output("modal", "is_open"),
@ -370,6 +163,18 @@ def toggle_modal(n1, n2, is_open):
return is_open
# callback pour le navmenu
@app.callback(
Output("offcanvas-menu", "is_open"),
[Input("navbar-toggler", "n_clicks")],
[dash.dependencies.State("offcanvas-menu", "is_open")],
)
def toggle_offcanvas(n, is_open):
if n:
return not is_open
return is_open
# on lance l'application
if __name__ == "__main__":
app.run(debug=True, port="8051")

Binary file not shown.

Binary file not shown.

78
3D_app/pages/ascan.py Normal file
View File

@ -0,0 +1,78 @@
import dash
from dash import html, callback, Input, Output, dcc
import dash_bootstrap_components as dbc
import plotly.graph_objects as go
import numpy as np
import plotly.express as px
import plotly.io as pio
from util import *
dash.register_page(__name__, path="/ascan", title='A-Scan filters', name='A-Scan filters')
# on définit le dossier et les fichiers à lire
dossier = "Dataset/Shear_transform"
fichiers_selectionnes = [
"Shear_x001-x101_y{:03d}_Rot00_transform.csv".format(i) for i in range(10, 14)
]
# dossier = "Dataset/Shear_Wave_Rot00_CSV_Data"
# fichiers_selectionnes = ['Shear_x001-x101_y{:03d}_Rot00.csv'.format(i) for i in range(10, 62)]
# on lit les fichiers et on les met dans un tableau
pre_volume = np.array(lire_fichier_csv(dossier, fichiers_selectionnes))
volume = pre_volume[:, ::32, :]
dim_x, dim_y, dim_z = volume.shape
X, Y, Z = np.mgrid[0:dim_x, 0:dim_y, 0:dim_z]
configAScan = {
"toImageButtonOptions": {
"format": "svg", # one of png, svg, jpeg, webp
"filename": "A-Scan",
"height": 1000,
"width": 1400,
"scale": 1, # Multiply title/legend/axis/canvas sizes by this factor
},
"displaylogo": False,
}
layout = html.Div(
[
dbc.Select(
id="select-ascan-filter",
options=[
{"label": "Option 1", "value": "1"},
{"label": "Option 2", "value": "2"},
],
style={"margin-bottom": "15px"},
),
dcc.Graph(
id="heatmap-ascan-solo",
config=configAScan,
style={"marginBottom": "15px"},
), # 'fig' is your 2D plotly figure
dcc.Slider(
id="layer-slider-ascan-solo",
min=1,
max=dim_x,
value=1,
step=1,
marks={
str(i): str(i) for i in range(1, dim_x + 1, max(1, int(dim_x / 20)))
},
),
],
style={"padding": "20px"},
)
# callback to update the heatmap
@callback(
Output("heatmap-ascan-solo", "figure"),
[Input("select-ascan-filter", "value"), Input("layer-slider-ascan-solo", "value")],
)
def update_heatmap_ascan(value, layer):
# TODO: implement the filter
fig = px.line(y=volume[layer - 1, :, 5], title="A-scan")
return fig

620
3D_app/pages/home.py Normal file
View File

@ -0,0 +1,620 @@
import dash
from dash import html, callback, Input, Output, dcc
import dash_bootstrap_components as dbc
import plotly.graph_objects as go
import numpy as np
import plotly.express as px
import plotly.io as pio
from util import *
dash.register_page(__name__, path="/")
# on définit le dossier et les fichiers à lire
dossier = "Dataset/Shear_transform"
fichiers_selectionnes = [
"Shear_x001-x101_y{:03d}_Rot00_transform.csv".format(i) for i in range(10, 14)
]
# dossier = "Dataset/Shear_Wave_Rot00_CSV_Data"
# fichiers_selectionnes = ['Shear_x001-x101_y{:03d}_Rot00.csv'.format(i) for i in range(10, 62)]
# on lit les fichiers et on les met dans un tableau
pre_volume = np.array(lire_fichier_csv(dossier, fichiers_selectionnes))
volume = pre_volume[:, ::32, :]
dim_x, dim_y, dim_z = volume.shape
X, Y, Z = np.mgrid[0:dim_x, 0:dim_y, 0:dim_z]
# on défini le thème de l'application
pio.templates.default = "plotly_dark"
# on crée le plot 3D
fig = go.Figure(
data=go.Volume(
x=X.flatten(),
y=Y.flatten(),
z=Z.flatten(),
value=volume.flatten(),
isomin=5000,
isomax=volume.max(),
opacity=0.1, # needs to be small to see through all surfaces
surface_count=20, # needs to be a large number for good volume rendering
colorscale="Jet",
)
)
# on défini les configurations des plots
config3DPlot = {
"toImageButtonOptions": {
"format": "svg", # one of png, svg, jpeg, webp
"filename": "3D-Plot",
"height": 1000,
"width": 1400,
"scale": 1, # Multiply title/legend/axis/canvas sizes by this factor
},
"displaylogo": False,
}
configAScan = {
"toImageButtonOptions": {
"format": "svg", # one of png, svg, jpeg, webp
"filename": "A-Scan",
"height": 1000,
"width": 1400,
"scale": 1, # Multiply title/legend/axis/canvas sizes by this factor
},
"displaylogo": False,
}
configBScanXY = {
"toImageButtonOptions": {
"format": "svg", # one of png, svg, jpeg, webp
"filename": "B-Scan XY",
"height": 1000,
"width": 1400,
"scale": 1, # Multiply title/legend/axis/canvas sizes by this factor
},
"displaylogo": False,
}
configBScanZX = {
"toImageButtonOptions": {
"format": "svg", # one of png, svg, jpeg, webp
"filename": "B-Scan ZX",
"height": 1000,
"width": 1400,
"scale": 1, # Multiply title/legend/axis/canvas sizes by this factor
},
"displaylogo": False,
}
# on crée les cartes
# carte pour le plot 3D
mesh_card = dbc.Card(
[
dbc.CardBody(
[
dbc.Row(
[
dbc.Col(
html.H2(
"3D Plot",
className="card-title",
style={"textAlign": "left"},
),
width="4",
),
dbc.Col(
dbc.Button(
html.I(className="bi bi-arrows-fullscreen"),
id="fullscreen-button-3dplot",
className="mb-3",
color="primary",
style={"marginBottom": "15px"},
),
),
],
),
dcc.Graph(
id="3dplot",
figure=fig,
config=config3DPlot,
style={"height": "411px", "marginBottom": "15px"},
), # 'fig' is your 3D plotly figure
dcc.Slider(
id="iso-slider",
min=volume.min(),
max=volume.max() / 2,
value=volume.min(),
marks={
str(i): str(i)
for i in range(
int(volume.min()),
int(volume.max() / 2) + 1,
int((volume.max() / 2 - volume.min()) / 10),
)
},
step=1,
),
dcc.RangeSlider(
id="y-slider",
min=0,
max=dim_y,
value=[0, dim_y / 2],
marks={
str(i): str(i)
for i in range(0, int(dim_y) + 1, max(1, int(dim_y / 20)))
},
step=1,
),
dbc.Modal(
[
dbc.ModalHeader(dbc.ModalTitle("3D Plot")),
dbc.ModalBody(
[
dcc.Graph(
id="3dplot-fullscreen",
figure=fig,
config=config3DPlot,
style={"marginBottom": "15px", "height": "90%"},
), # 'fig' is your 3D plotly figure
dcc.Slider(
id="iso-slider-fullscreen",
min=volume.min(),
max=volume.max() / 2,
value=volume.min(),
marks={
str(i): str(i)
for i in range(
int(volume.min()),
int(volume.max() / 2) + 1,
int((volume.max() / 2 - volume.min()) / 10),
)
},
step=1,
),
dcc.RangeSlider(
id="y-slider-fullscreen",
min=0,
max=dim_y,
value=[0, dim_y / 2],
marks={
str(i): str(i)
for i in range(
0, int(dim_y) + 1, max(1, int(dim_y / 20))
)
},
step=1,
),
]
),
],
id="modal-3dplot",
fullscreen=True,
),
]
)
]
)
# carte pour le A-scan
Ascan_card = dbc.Card(
[
dbc.CardBody(
[
dbc.Row(
[
dbc.Col(
html.H2(
"A-scan",
className="card-title",
style={"textAlign": "left"},
),
width="4",
),
dbc.Col(
dbc.Button(
html.I(className="bi bi-arrows-fullscreen"),
id="fullscreen-button-ascan",
className="mb-3",
color="primary",
style={"marginBottom": "15px"},
),
),
],
),
dcc.Graph(
id="heatmap-ascan",
config=configAScan,
style={"marginBottom": "15px"},
), # 'fig' is your 2D plotly figure
dcc.Slider(
id="layer-slider-ascan",
min=1,
max=dim_x,
value=1,
step=1,
marks={
str(i): str(i)
for i in range(1, dim_x + 1, max(1, int(dim_x / 20)))
},
),
dbc.Modal(
[
dbc.ModalHeader(dbc.ModalTitle("A-Scan")),
dbc.ModalBody(
[
dcc.Graph(
id="heatmap-ascan-fullscreen",
config=configAScan,
style={"marginBottom": "15px"},
), # 'fig' is your 2D plotly figure
dcc.Slider(
id="layer-slider-ascan-fullscreen",
min=1,
max=dim_x,
value=1,
step=1,
marks={
str(i): str(i)
for i in range(
1, dim_x + 1, max(1, int(dim_x / 20))
)
},
),
]
),
],
id="modal-ascan",
fullscreen=True,
),
]
)
]
)
# carte pour le B-scan XY
Bscan_card_xy = dbc.Card(
[
dbc.CardBody(
[
dbc.Row(
[
dbc.Col(
html.H2(
"B-scan XY",
className="card-title",
style={"textAlign": "left"},
),
width="4",
),
dbc.Col(
dbc.Button(
html.I(className="bi bi-arrows-fullscreen"),
id="fullscreen-button-bscan-xy",
className="mb-3",
color="primary",
style={"marginBottom": "15px"},
),
),
],
),
dcc.Graph(
id="heatmap-bscan-xy",
config=configBScanXY,
style={"marginBottom": "15px"},
), # 'fig' is your 2D plotly figure
dcc.Slider(
id="layer-slider-bscan-xy",
min=1,
max=dim_x,
value=1,
step=1,
marks={
str(i): str(i)
for i in range(1, dim_x + 1, max(1, int(dim_x / 20)))
},
),
dbc.Modal(
[
dbc.ModalHeader(dbc.ModalTitle("B-Scan XY")),
dbc.ModalBody(
[
dcc.Graph(
id="heatmap-bscan-xy-fullscreen",
config=configBScanXY,
style={"marginBottom": "15px"},
), # 'fig' is your 2D plotly figure
dcc.Slider(
id="layer-slider-bscan-xy-fullscreen",
min=1,
max=dim_x,
value=1,
step=1,
marks={
str(i): str(i)
for i in range(
1, dim_x + 1, max(1, int(dim_x / 20))
)
},
),
]
),
],
id="modal-bscan-xy",
fullscreen=True,
),
]
)
]
)
# carte pour le B-scan ZX
Bscan_card_zx = dbc.Card(
[
dbc.CardBody(
[
dbc.Row(
[
dbc.Col(
html.H2(
"B-scan ZX",
className="card-title",
style={"textAlign": "left"},
),
width="4",
),
dbc.Col(
dbc.Button(
html.I(className="bi bi-arrows-fullscreen"),
id="fullscreen-button-bscan-zx",
className="mb-3",
color="primary",
style={"marginBottom": "15px"},
),
),
],
),
dcc.Graph(
id="heatmap-bscan-zx",
config=configBScanZX,
style={"marginBottom": "15px"},
), # 'fig' is your 2D plotly figure
dcc.Slider(
id="layer-slider-bscan-zx",
min=1,
max=dim_z - 1,
value=1,
step=1,
marks={
str(i): str(i)
for i in range(1, dim_z + 1, max(1, int(dim_z / 20)))
},
),
dbc.Modal(
[
dbc.ModalHeader(dbc.ModalTitle("B-Scan XY")),
dbc.ModalBody(
[
dcc.Graph(
id="heatmap-bscan-zx-fullscreen",
config=configBScanZX,
style={"marginBottom": "15px"},
), # 'fig' is your 2D plotly figure
dcc.Slider(
id="layer-slider-bscan-zx-fullscreen",
min=1,
max=dim_z - 1,
value=1,
step=1,
marks={
str(i): str(i)
for i in range(
1, dim_z + 1, max(1, int(dim_z / 20))
)
},
),
],
),
],
id="modal-bscan-xy",
fullscreen=True,
),
]
)
]
)
layout = html.Div(
[
dbc.Row(
[dbc.Col(Ascan_card, width=6), dbc.Col(mesh_card, width=6)],
style={"margin": "8px"},
),
dbc.Row(
[dbc.Col(Bscan_card_xy, width=6), dbc.Col(Bscan_card_zx, width=6)],
style={"margin": "8px"},
),
]
)
# on défini les callbacks
# callback pour le plot 3D
@callback(
Output("3dplot", "figure"),
[Input("iso-slider", "value"), Input("y-slider", "value")],
)
def update_3dplot(iso_value, y_values):
y_min, y_max = y_values
selected_volume = volume[0:dim_x, int(y_min) : int(y_max), 0:dim_z]
X, Y, Z = np.mgrid[
0 : selected_volume.shape[0],
0 : selected_volume.shape[1],
0 : selected_volume.shape[2],
]
fig = go.Figure(
data=go.Volume(
x=X.flatten(),
y=Y.flatten(),
z=Z.flatten(),
value=selected_volume.flatten(),
isomin=iso_value,
isomax=selected_volume.max(),
opacity=0.1,
surface_count=20,
colorscale="Jet",
)
)
return fig
# callback pour le plot 3D en plein écran
@callback(
Output("3dplot-fullscreen", "figure"),
[Input("iso-slider-fullscreen", "value"), Input("y-slider-fullscreen", "value")],
)
def update_3dplot_fullscreen(iso_value, y_values):
y_min, y_max = y_values
selected_volume = volume[0:dim_x, int(y_min) : int(y_max), 0:dim_z]
X, Y, Z = np.mgrid[
0 : selected_volume.shape[0],
0 : selected_volume.shape[1],
0 : selected_volume.shape[2],
]
fig = go.Figure(
data=go.Volume(
x=X.flatten(),
y=Y.flatten(),
z=Z.flatten(),
value=selected_volume.flatten(),
isomin=iso_value,
isomax=selected_volume.max(),
opacity=0.1,
surface_count=20,
colorscale="Jet",
)
)
return fig
# callback pour le A-scan
@callback(
Output("heatmap-ascan", "figure"),
Input("layer-slider-ascan", "value"),
)
def update_heatmap_ascan(layer):
fig = px.line(y=volume[layer - 1, :, 5], title="A-scan")
return fig
# callback pour le A-scan en plein écran
@callback(
Output("heatmap-ascan-fullscreen", "figure"),
Input("layer-slider-ascan-fullscreen", "value"),
)
def update_heatmap_ascan_fullscreen(layer):
fig = px.line(y=volume[layer - 1, :, 5], title="A-scan")
return fig
# callback pour les B-scan XY
@callback(Output("heatmap-bscan-xy", "figure"), Input("layer-slider-bscan-xy", "value"))
def update_heatmap_bscan_xy(layer):
fig = px.imshow(
volume[layer - 1, :, :],
color_continuous_scale="Jet",
aspect="auto",
title="B-scan XY",
)
return fig
# callback pour les B-scan XY en plein écran
@callback(
Output("heatmap-bscan-xy-fullscreen", "figure"),
Input("layer-slider-bscan-xy-fullscreen", "value"),
)
def update_heatmap_bscan_xy_fullscreen(layer):
fig = px.imshow(
volume[layer - 1, :, :],
color_continuous_scale="Jet",
aspect="auto",
title="B-scan XY",
)
return fig
# callback pour les B-scan ZX
@callback(Output("heatmap-bscan-zx", "figure"), Input("layer-slider-bscan-zx", "value"))
def update_heatmap_bscan_zx(layer):
fig = go.Figure(data=go.Heatmap(z=volume[:, :, layer], colorscale="Jet"))
return fig
# callback pour les B-scan ZX en plein écran
@callback(
Output("heatmap-bscan-zx-fullscreen", "figure"),
Input("layer-slider-bscan-zx-fullscreen", "value"),
)
def update_heatmap_bscan_zx_fullscreen(layer):
fig = go.Figure(data=go.Heatmap(z=volume[:, :, layer], colorscale="Jet"))
return fig
# callback pour le plein écran du plot 3D
@callback(
Output("modal-3dplot", "is_open"),
[Input("fullscreen-button-3dplot", "n_clicks")],
[dash.dependencies.State("modal-3dplot", "is_open")],
)
def toggle_fullscreen_3dplot(n1, is_open):
if n1:
return not is_open
return is_open
# callback pour le plein écran du A-scan
@callback(
Output("modal-ascan", "is_open"),
[Input("fullscreen-button-ascan", "n_clicks")],
[dash.dependencies.State("modal-ascan", "is_open")],
)
def toggle_fullscreen_ascan(n1, is_open):
if n1:
return not is_open
return is_open
# callback pour le plein écran du B-scan XY
@callback(
Output("modal-bscan-xy", "is_open"),
[Input("fullscreen-button-bscan-xy", "n_clicks")],
[dash.dependencies.State("modal-bscan-xy", "is_open")],
)
def toggle_fullscreen_bscan_xy(n1, is_open):
if n1:
return not is_open
return is_open
# callback pour le plein écran du B-scan ZX
@callback(
Output("modal-bscan-zx", "is_open"),
[Input("fullscreen-button-bscan-zx", "n_clicks")],
[dash.dependencies.State("modal-bscan-zx", "is_open")],
)
def toggle_fullscreen_bscan_zx(n1, is_open):
if n1:
return not is_open
return is_open