Arts-of-coding commited on
Commit
6b4eab9
·
verified ·
1 Parent(s): 6119c8b

Rename pages/ctrl_suture.py to pages/No_suture.py

Browse files
pages/{ctrl_suture.py → No_suture.py} RENAMED
@@ -2,6 +2,14 @@
2
  # Shoutout to Coding-with-Adam for the initial template of the project:
3
  # https://github.com/Coding-with-Adam/Dash-by-Plotly/blob/master/Dash%20Components/Graph/dash-graph.py
4
 
 
 
 
 
 
 
 
 
5
  import dash
6
  from dash import dcc, html, Output, Input, callback
7
  import plotly.express as px
@@ -9,6 +17,347 @@ import dash_callback_chain
9
  import yaml
10
  import polars as pl
11
  import os
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  pl.enable_string_cache(False)
13
 
14
  dash.register_page(__name__, location="sidebar")
@@ -113,51 +462,51 @@ tab1_content = html.Div([
113
  options=df.columns),
114
  html.Label("N Genes by Counts"),
115
  dcc.RangeSlider(
116
- id='range-slider_db2-1',
117
  step=250,
118
  value=[min_value, max_value],
119
  marks={i: str(i) for i in range(min_value, max_value + 1, 250)},
120
  ),
121
- dcc.Input(id='min-slider_db2-1', type='number', value=min_value, debounce=True),
122
- dcc.Input(id='max-slider_db2-1', type='number', value=max_value, debounce=True),
123
  html.Label("Total Counts"),
124
  dcc.RangeSlider(
125
- id='range-slider_db2-2',
126
  step=7500,
127
  value=[min_value_2, max_value_2],
128
  marks={i: str(i) for i in range(min_value_2, max_value_2 + 1, 7500)},
129
  ),
130
- dcc.Input(id='min-slider_db2-2', type='number', value=min_value_2, debounce=True),
131
- dcc.Input(id='max-slider_db2-2', type='number', value=max_value_2, debounce=True),
132
  html.Label("Percent Mitochondrial Genes"),
133
  dcc.RangeSlider(
134
- id='range-slider_db2-3',
135
  step=5,
136
  min=0,
137
  max=100,
138
  value=[min_value_3, max_value_3],
139
  ),
140
- dcc.Input(id='min-slider_db2-3', type='number', value=min_value_3, debounce=True),
141
- dcc.Input(id='max-slider_db2-3', type='number', value=max_value_3, debounce=True),
142
  html.Div([
143
- dcc.Graph(id='pie-graph_db2', figure={}, className='four columns',config=config_fig),
144
- dcc.Graph(id='my-graph_db2', figure={}, clickData=None, hoverData=None,
145
  className='four columns',config=config_fig
146
  ),
147
- dcc.Graph(id='scatter-plot_db2', figure={}, className='four columns',config=config_fig)
148
  ]),
149
  html.Div([
150
- dcc.Graph(id='scatter-plot_db2-2', figure={}, className='four columns',config=config_fig)
151
  ]),
152
  html.Div([
153
- dcc.Graph(id='scatter-plot_db2-3', figure={}, className='four columns',config=config_fig)
154
  ]),
155
  html.Div([
156
- dcc.Graph(id='scatter-plot_db2-4', figure={}, className='four columns',config=config_fig)
157
  ]),
158
  ])
159
 
160
- # Create the second tab content with scatter-plot_db2-5 and scatter-plot_db2-6
161
  tab2_content = html.Div([
162
  html.Div([
163
  html.Label("S-cycle genes"),
@@ -267,20 +616,20 @@ tab2_content = html.Div([
267
 
268
  ]),
269
  html.Div([
270
- dcc.Graph(id='scatter-plot_db2-5', figure={}, className='three columns',config=config_fig)
271
  ]),
272
  html.Div([
273
- dcc.Graph(id='scatter-plot_db2-6', figure={}, className='three columns',config=config_fig)
274
  ]),
275
  html.Div([
276
- dcc.Graph(id='scatter-plot_db2-7', figure={}, className='three columns',config=config_fig)
277
  ]),
278
  html.Div([
279
- dcc.Graph(id='scatter-plot_db2-8', figure={}, className='three columns',config=config_fig)
280
  ]),
281
  ])
282
 
283
- # Create the second tab content with scatter-plot_db2-5 and scatter-plot_db2-6
284
  tab3_content = html.Div([
285
  html.Div([
286
  html.Label("UMAP condition 1"),
@@ -290,23 +639,23 @@ tab3_content = html.Div([
290
  dcc.Dropdown(id='dpdn6', value="n_genes_by_counts", multi=False,
291
  options=df.columns),
292
  html.Div([
293
- dcc.Graph(id='scatter-plot_db2-9', figure={}, className='four columns',config=config_fig)
294
  ]),
295
  html.Div([
296
- dcc.Graph(id='scatter-plot_db2-10', figure={}, className='four columns',config=config_fig)
297
  ]),
298
  html.Div([
299
- dcc.Graph(id='scatter-plot_db2-11', figure={}, className='four columns',config=config_fig)
300
  ]),
301
  html.Div([
302
- dcc.Graph(id='my-graph_db22', figure={}, clickData=None, hoverData=None,
303
  className='four columns',config=config_fig
304
  )
305
  ]),
306
  ]),
307
  ])
308
  # html.Div([
309
- # dcc.Graph(id='scatter-plot_db2-12', figure={}, className='four columns',config=config_fig)
310
  # ]),
311
 
312
 
@@ -317,7 +666,7 @@ tab4_content = html.Div([
317
  options=df.columns),
318
  ]),
319
  html.Div([
320
- dcc.Graph(id='scatter-plot_db2-12', figure={}, className='row',style={'width': '100vh', 'height': '90vh'}), # px)
321
  ]),
322
  ])
323
 
@@ -337,63 +686,63 @@ layout = html.Div([
337
 
338
  # Define the circular callback
339
  @callback(
340
- Output("min-slider_db2-1", "value"),
341
- Output("max-slider_db2-1", "value"),
342
- Output("min-slider_db2-2", "value"),
343
- Output("max-slider_db2-2", "value"),
344
- Output("min-slider_db2-3", "value"),
345
- Output("max-slider_db2-3", "value"),
346
- Input("min-slider_db2-1", "value"),
347
- Input("max-slider_db2-1", "value"),
348
- Input("min-slider_db2-2", "value"),
349
- Input("max-slider_db2-2", "value"),
350
- Input("min-slider_db2-3", "value"),
351
- Input("max-slider_db2-3", "value"),
352
 
353
  )
354
  def circular_callback(min_1, max_1, min_2, max_2, min_3, max_3):
355
  return min_1, max_1, min_2, max_2, min_3, max_3
356
 
357
  @callback(
358
- Output('range-slider_db2-1', 'value'),
359
- Output('range-slider_db2-2', 'value'),
360
- Output('range-slider_db2-3', 'value'),
361
- Input('min-slider_db2-1', 'value'),
362
- Input('max-slider_db2-1', 'value'),
363
- Input('min-slider_db2-2', 'value'),
364
- Input('max-slider_db2-2', 'value'),
365
- Input('min-slider_db2-3', 'value'),
366
- Input('max-slider_db2-3', 'value'),
367
 
368
  )
369
  def update_slider_values(min_1, max_1, min_2, max_2, min_3, max_3):
370
  return [min_1, max_1], [min_2, max_2], [min_3, max_3]
371
 
372
  @callback(
373
- Output(component_id='my-graph_db2', component_property='figure'),
374
- Output(component_id='pie-graph_db2', component_property='figure'),
375
- Output(component_id='scatter-plot_db2', component_property='figure'),
376
- Output(component_id='scatter-plot_db2-2', component_property='figure'),
377
- Output(component_id='scatter-plot_db2-3', component_property='figure'),
378
- Output(component_id='scatter-plot_db2-4', component_property='figure'), # Add this new scatter plot
379
- Output(component_id='scatter-plot_db2-5', component_property='figure'),
380
- Output(component_id='scatter-plot_db2-6', component_property='figure'),
381
- Output(component_id='scatter-plot_db2-7', component_property='figure'),
382
- Output(component_id='scatter-plot_db2-8', component_property='figure'),
383
- Output(component_id='scatter-plot_db2-9', component_property='figure'),
384
- Output(component_id='scatter-plot_db2-10', component_property='figure'),
385
- Output(component_id='scatter-plot_db2-11', component_property='figure'),
386
- Output(component_id='scatter-plot_db2-12', component_property='figure'),
387
- Output(component_id='my-graph_db22', component_property='figure'),
388
  Input(component_id='dpdn2', component_property='value'),
389
  Input(component_id='dpdn3', component_property='value'),
390
  Input(component_id='dpdn4', component_property='value'),
391
  Input(component_id='dpdn5', component_property='value'),
392
  Input(component_id='dpdn6', component_property='value'),
393
  Input(component_id='dpdn7', component_property='value'),
394
- Input(component_id='range-slider_db2-1', component_property='value'),
395
- Input(component_id='range-slider_db2-2', component_property='value'),
396
- Input(component_id='range-slider_db2-3', component_property='value'),
397
 
398
  )
399
 
@@ -415,7 +764,7 @@ def update_graph_and_pie_chart(col_chosen, s_chosen, g2m_chosen, condition1_chos
415
  dff = dff.sort(col_chosen)
416
 
417
  # Plot figures
418
- fig_violin_db2 = px.violin(data_frame=dff, x=col_chosen, y=col_features, box=True, points="all",
419
  color=col_chosen, hover_name=col_chosen,template="seaborn")
420
 
421
  # Cache commonly used subexpressions
@@ -470,70 +819,70 @@ def update_graph_and_pie_chart(col_chosen, s_chosen, g2m_chosen, condition1_chos
470
  #expression_means = expression_means.select(["batch", "Gene", "Expression"] + condition3_chosen)
471
  category_counts = category_counts.sort(col_chosen)
472
 
473
- fig_pie_db2 = px.pie(category_counts, values="normalized_count", names=col_chosen, labels=col_chosen, hole=.3, title=pie_title, template="seaborn")
474
 
475
  #labels = category_counts[col_chosen].to_list()
476
  #values = category_counts["normalized_count"].to_list()
477
 
478
  # Create the scatter plots
479
- fig_scatter_db2 = px.scatter(data_frame=dff, x='X_umap-0', y='X_umap-1', color=col_chosen,
480
  labels={'X_umap-0': 'umap1' , 'X_umap-1': 'umap2'},
481
  hover_name='batch',template="seaborn")
482
 
483
- fig_scatter_db2_2 = px.scatter(data_frame=dff, x='X_umap-0', y='X_umap-1', color=col_mt,
484
  labels={'X_umap-0': 'umap1' , 'X_umap-1': 'umap2'},
485
  hover_name='batch',template="seaborn")
486
 
487
- fig_scatter_db2_3 = px.scatter(data_frame=dff, x='X_umap-0', y='X_umap-1', color=col_features,
488
  labels={'X_umap-0': 'umap1' , 'X_umap-1': 'umap2'},
489
  hover_name='batch',template="seaborn")
490
 
491
 
492
- fig_scatter_db2_4 = px.scatter(data_frame=dff, x='X_umap-0', y='X_umap-1', color=col_counts,
493
  labels={'X_umap-0': 'umap1' , 'X_umap-1': 'umap2'},
494
  hover_name='batch',template="seaborn")
495
 
496
- fig_scatter_db2_5 = px.scatter(data_frame=dff, x='X_umap-0', y='X_umap-1', color=s_chosen,
497
  labels={'X_umap-0': 'umap1' , 'X_umap-1': 'umap2'},
498
  hover_name='batch', title="S-cycle gene:",template="seaborn")
499
 
500
- fig_scatter_db2_6 = px.scatter(data_frame=dff, x='X_umap-0', y='X_umap-1', color=g2m_chosen,
501
  labels={'X_umap-0': 'umap1' , 'X_umap-1': 'umap2'},
502
  hover_name='batch', title="G2M-cycle gene:",template="seaborn")
503
 
504
- fig_scatter_db2_7 = px.scatter(data_frame=dff, x='X_umap-0', y='X_umap-1', color="S_score",
505
  labels={'X_umap-0': 'umap1' , 'X_umap-1': 'umap2'},
506
  hover_name='batch', title="S score:",template="seaborn")
507
 
508
- fig_scatter_db2_8 = px.scatter(data_frame=dff, x='X_umap-0', y='X_umap-1', color="G2M_score",
509
  labels={'X_umap-0': 'umap1' , 'X_umap-1': 'umap2'},
510
  hover_name='batch', title="G2M score:",template="seaborn")
511
 
512
  # Sort values of custom in-between
513
  dff = dff.sort(condition1_chosen)
514
 
515
- fig_scatter_db2_9 = px.scatter(data_frame=dff, x='X_umap-0', y='X_umap-1', color=condition1_chosen,
516
  labels={'X_umap-0': 'umap1' , 'X_umap-1': 'umap2'},
517
  hover_name='batch',template="seaborn")
518
 
519
- fig_scatter_db2_10 = px.scatter(data_frame=dff, x='X_umap-0', y='X_umap-1', color=condition2_chosen,
520
  labels={'X_umap-0': 'umap1' , 'X_umap-1': 'umap2'},
521
  hover_name='batch',template="seaborn")
522
 
523
- fig_scatter_db2_11 = px.scatter(data_frame=dff, x=condition1_chosen, y=condition2_chosen, color=condition1_chosen,
524
  #labels={'X_umap-0': 'umap1' , 'X_umap-1': 'umap2'},
525
  hover_name='batch',template="seaborn")
526
 
527
- fig_scatter_db2_12 = px.scatter(data_frame=expression_means, x="Gene", y=col_chosen, color="Mean expression",
528
  size="percentage", size_max = 20,
529
  #labels={'X_umap-0': 'umap1' , 'X_umap-1': 'umap2'},
530
  hover_name=col_chosen,template="seaborn")
531
 
532
- fig_violin_db22 = px.violin(data_frame=dff, x=condition1_chosen, y=condition2_chosen, box=True, points="all",
533
  color=condition1_chosen, hover_name=condition1_chosen,template="seaborn")
534
 
535
 
536
- return fig_violin_db2, fig_pie_db2, fig_scatter_db2, fig_scatter_db2_2, fig_scatter_db2_3, fig_scatter_db2_4, fig_scatter_db2_5, fig_scatter_db2_6, fig_scatter_db2_7, fig_scatter_db2_8, fig_scatter_db2_9, fig_scatter_db2_10, fig_scatter_db2_11, fig_scatter_db2_12, fig_violin_db22
537
 
538
  # Set http://localhost:5000/ in web browser
539
  # Now create your regular FASTAPI application
 
2
  # Shoutout to Coding-with-Adam for the initial template of the project:
3
  # https://github.com/Coding-with-Adam/Dash-by-Plotly/blob/master/Dash%20Components/Graph/dash-graph.py
4
 
5
+ import dash
6
+ from dash import dcc, html, Output, Input, callback
7
+ import plotly.express as px
8
+ import dash_callback_chain
9
+ import yaml# Dash app to visualize scRNA-seq data quality control metrics from scanpy objects
10
+ # Shoutout to Coding-with-Adam for the initial template of the project:
11
+ # https://github.com/Coding-with-Adam/Dash-by-Plotly/blob/master/Dash%20Components/Graph/dash-graph.py
12
+
13
  import dash
14
  from dash import dcc, html, Output, Input, callback
15
  import plotly.express as px
 
17
  import yaml
18
  import polars as pl
19
  import os
20
+ from natsort import natsorted
21
+ #pl.enable_string_cache(False)
22
+
23
+ dash.register_page(__name__, location="sidebar")
24
+
25
+ dataset = "datasuture/ctrl/No_suture_polars"
26
+
27
+ # Set custom resolution for plots:
28
+ config_fig = {
29
+ 'toImageButtonOptions': {
30
+ 'format': 'svg',
31
+ 'filename': 'custom_image',
32
+ 'height': 600,
33
+ 'width': 700,
34
+ 'scale': 1,
35
+ }
36
+ }
37
+ from adlfs import AzureBlobFileSystem
38
+ mountpount=os.environ['AZURE_MOUNT_POINT'],
39
+ AZURE_STORAGE_ACCESS_KEY=os.getenv('AZURE_STORAGE_ACCESS_KEY')
40
+ AZURE_STORAGE_ACCOUNT=os.getenv('AZURE_STORAGE_ACCOUNT')
41
+
42
+ # Load in config file
43
+ config_path = "./data/config.yaml"
44
+
45
+ # Add the read-in data from the yaml file
46
+ def read_config(filename):
47
+ with open(filename, 'r') as yaml_file:
48
+ config = yaml.safe_load(yaml_file)
49
+ return config
50
+
51
+ config = read_config(config_path)
52
+ path_parquet = config.get("path_parquet")
53
+ col_batch = config.get("col_batch")
54
+ col_features = config.get("col_features")
55
+ col_counts = config.get("col_counts")
56
+ col_mt = config.get("col_mt")
57
+
58
+ #filepath = f"az://{path_parquet}"
59
+
60
+ storage_options={'account_name': AZURE_STORAGE_ACCOUNT, 'account_key': AZURE_STORAGE_ACCESS_KEY} #, 'anon': False
61
+ #azfs = AzureBlobFileSystem(**storage_options )
62
+
63
+ # Load in multiple dataframes
64
+ df = pl.scan_parquet(f"az://{dataset}.parquet", storage_options=storage_options).collect()
65
+
66
+ # Create the second tab content with scatter-plot_db0-5 and scatter-plot_db0-6
67
+ tab2_content = html.Div([
68
+ html.Div([
69
+ html.Label("S-cycle genes"),
70
+ dcc.Dropdown(id='dpdn3', value="Mcm5", multi=False,
71
+ options=[
72
+ "Cdc45",
73
+ "Uhrf1",
74
+ "Mcm2",
75
+ "Slbp",
76
+ "Mcm5",
77
+ "Pola1",
78
+ "Gmnn",
79
+ "Cdc6",
80
+ "Rrm2",
81
+ "Atad2",
82
+ "Dscc1",
83
+ "Mcm4",
84
+ "Chaf1b",
85
+ "Rfc2",
86
+ "Msh2",
87
+ "Fen1",
88
+ "Hells",
89
+ "Prim1",
90
+ "Tyms",
91
+ "Mcm6",
92
+ "Wdr76",
93
+ "Rad51",
94
+ "Pcna",
95
+ "Ccne2",
96
+ "Casp8ap2",
97
+ "Usp1",
98
+ "Nasp",
99
+ "Rpa2",
100
+ "Ung",
101
+ "Rad51ap1",
102
+ "Blm",
103
+ "Pold3",
104
+ "Rrm1",
105
+ "Cenpu",
106
+ "Gins2",
107
+ "Tipin",
108
+ "Brip1",
109
+ "Dtl",
110
+ "Exo1",
111
+ "Ubr7",
112
+ "Clspn",
113
+ "E2f8",
114
+ "Cdca7"
115
+ ]),
116
+ html.Label("G2M-cycle genes"),
117
+ dcc.Dropdown(id='dpdn4', value="Top2a", multi=False,
118
+ options=[
119
+ "Ube2c",
120
+ "Lbr",
121
+ "Ctcf",
122
+ "Cdc20",
123
+ "Cbx5",
124
+ "Kif11",
125
+ "Anp32e",
126
+ "Birc5",
127
+ "Cdk1",
128
+ "Tmpo",
129
+ "Hmmr",
130
+ "Pimreg",
131
+ "Aurkb",
132
+ "Top2a",
133
+ "Gtse1",
134
+ "Rangap1",
135
+ "Cdca3",
136
+ "Ndc80",
137
+ "Kif20b",
138
+ "Cenpf",
139
+ "Nek2",
140
+ "Nuf2",
141
+ "Nusap1",
142
+ "Bub1",
143
+ "Tpx2",
144
+ "Aurka",
145
+ "Ect2",
146
+ "Cks1b",
147
+ "Kif2c",
148
+ "Cdca8",
149
+ "Cenpa",
150
+ "Mki67",
151
+ "Ccnb2",
152
+ "Kif23",
153
+ "Smc4",
154
+ "G2e3",
155
+ "Tubb4b",
156
+ "Anln",
157
+ "Tacc3",
158
+ "Dlgap5",
159
+ "Ckap2",
160
+ "Ncapd2",
161
+ "Ttk",
162
+ "Ckap5",
163
+ "Cdc25c",
164
+ "Hjurp",
165
+ "Cenpe",
166
+ "Ckap2l",
167
+ "Cdca2",
168
+ "Hmgb2",
169
+ "Cks2",
170
+ "Psrc1",
171
+ "Gas2l3"
172
+ ]),
173
+ ]),
174
+ html.Div([
175
+ dcc.Graph(id='scatter-plot_db0-5', figure={}, className='three columns',config=config_fig)
176
+ ]),
177
+ html.Div([
178
+ dcc.Graph(id='scatter-plot_db0-6', figure={}, className='three columns',config=config_fig)
179
+ ]),
180
+ html.Div([
181
+ dcc.Graph(id='scatter-plot_db0-7', figure={}, className='three columns',config=config_fig)
182
+ ]),
183
+ html.Div([
184
+ dcc.Graph(id='scatter-plot_db0-8', figure={}, className='three columns',config=config_fig)
185
+ ]),
186
+ ])
187
+
188
+ # Create the second tab content with scatter-plot_db0-5 and scatter-plot_db0-6
189
+ tab3_content = html.Div([
190
+ html.Div([
191
+ html.Label("UMAP condition 1"),
192
+ dcc.Dropdown(id='dpdn5', value="condition", multi=False,
193
+ options=df.columns),
194
+ html.Label("UMAP condition 2"),
195
+ dcc.Dropdown(id='dpdn6', value="Pax6", multi=False,
196
+ options=df.columns),
197
+ html.Div([
198
+ dcc.Graph(id='scatter-plot_db0-9', figure={}, className='four columns', hoverData=None ,config=config_fig)
199
+ ]),
200
+ html.Div([
201
+ dcc.Graph(id='scatter-plot_db0-10', figure={}, className='four columns', hoverData=None, config=config_fig)
202
+ ]),
203
+ html.Div([
204
+ dcc.Graph(id='scatter-plot_db0-11', figure={}, className='four columns',config=config_fig)
205
+ ]),
206
+ html.Div([
207
+ dcc.Graph(id='my-graph_db02', figure={}, clickData=None, hoverData=None,
208
+ className='four columns',config=config_fig
209
+ )
210
+ ]),
211
+ ]),
212
+ ])
213
+
214
+ tab4_content = html.Div([
215
+ html.Label("Column chosen"),
216
+ dcc.Dropdown(id='dpdn2', value="cell states", multi=False,
217
+ options=df.columns),
218
+ html.Div([
219
+ html.Label("Multi gene"),
220
+ dcc.Dropdown(id='dpdn7', value=["Pax6","Sox9","Cdk8","Il31ra","Gpha2",
221
+ "Areg","Krt13","Krt19","Psca","Muc20",
222
+ "S100a9","Lama3","Itgb4","Itga6","Thy1","Dcn","Scn7a",
223
+ "Cdh19","Mpz","Ptprc","Cd52","Cd69","Cd86","Rgs5","Des","Myh11","Cd93","Pecam1",
224
+ "Abcg2","Lyve1","Mki67"], multi=True,
225
+ options=df.columns),
226
+ ]),
227
+ html.Div([
228
+ dcc.Graph(id='scatter-plot_db0-12', figure={}, className='row',style={'width': '100vh', 'height': '90vh'})
229
+ ]),
230
+ ])
231
+
232
+ # Define the tabs layout
233
+ layout = html.Div([
234
+ html.H1(f'Dataset analysis dashboard: {dataset}'),
235
+ dcc.Tabs(id='tabs', style= {'width': 600,
236
+ 'font-size': '100%',
237
+ 'height': 50}, value='tab1',children=[
238
+ #dcc.Tab(label='Dataset', value='tab0', children=tab0_content),
239
+ #dcc.Tab(label='QC', value='tab1', children=tab1_content),
240
+ dcc.Tab(label='UMAP visualisation', value='tab3', children=tab3_content),
241
+ dcc.Tab(label='Multi dot', value='tab4', children=tab4_content),
242
+ dcc.Tab(label='Cell cycle', value='tab2', children=tab2_content),
243
+ ]),
244
+ ])
245
+
246
+ @callback(
247
+ Output(component_id='scatter-plot_db0-5', component_property='figure'),
248
+ Output(component_id='scatter-plot_db0-6', component_property='figure'),
249
+ Output(component_id='scatter-plot_db0-7', component_property='figure'),
250
+ Output(component_id='scatter-plot_db0-8', component_property='figure'),
251
+ Output(component_id='scatter-plot_db0-9', component_property='figure'),
252
+ Output(component_id='scatter-plot_db0-10', component_property='figure'),
253
+ Output(component_id='scatter-plot_db0-11', component_property='figure'),
254
+ Output(component_id='scatter-plot_db0-12', component_property='figure'),
255
+ Output(component_id='my-graph_db02', component_property='figure'),
256
+ Input(component_id='dpdn2', component_property='value'),
257
+ Input(component_id='dpdn3', component_property='value'),
258
+ Input(component_id='dpdn4', component_property='value'),
259
+ Input(component_id='dpdn5', component_property='value'),
260
+ Input(component_id='dpdn6', component_property='value'),
261
+ Input(component_id='dpdn7', component_property='value'),
262
+
263
+ )
264
+
265
+ def update_graph_and_pie_chart(col_chosen, s_chosen, g2m_chosen, condition1_chosen, condition2_chosen, condition3_chosen): #, range_value_1, range_value_2, range_value_3 batch_chosen,
266
+ batch_chosen = df[col_chosen].unique().to_list()
267
+ dff = df.filter(
268
+ (pl.col(col_chosen).cast(str).is_in(batch_chosen)) #&
269
+ )
270
+ # Select ordering of plots
271
+ if condition1_chosen == "integrated_cell_states":
272
+ cat_ord= {condition1_chosen: natsorted(dff[condition1_chosen].unique())}
273
+ else:
274
+ cat_ord= {condition1_chosen: natsorted(dff[condition1_chosen].unique())}
275
+
276
+ # Calculate the mean expression
277
+
278
+ # Melt wide format DataFrame into long format
279
+ # Specify batch column as string type and gene columns as float type
280
+ list_conds = condition3_chosen
281
+ list_conds += [col_chosen]
282
+ dff_pre = dff.select(list_conds)
283
+
284
+ # Melt wide format DataFrame into long format
285
+ dff_long = dff_pre.melt(id_vars=col_chosen, variable_name="Gene", value_name="Mean expression")
286
+
287
+ # Calculate the mean expression levels for each gene in each region
288
+ expression_means = dff_long.lazy().group_by([col_chosen, "Gene"]).agg(pl.mean("Mean expression")).collect() #
289
+
290
+ # Calculate the percentage total expressed
291
+ dff_long1 = dff_pre.melt(id_vars=col_chosen, variable_name="Gene")#.group_by(pl.all()).agg(pl.len())
292
+ count = 1
293
+ dff_long2 = dff_long1.with_columns(pl.lit(count).alias("len"))
294
+ dff_long3 = dff_long2.filter(pl.col("value") > 0).group_by([col_chosen, "Gene"]).agg(pl.sum("len").alias("len"))
295
+ dff_long4 = dff_long2.group_by([col_chosen, "Gene"]).agg(pl.sum("len").alias("total"))
296
+ dff_5 = dff_long4.join(dff_long3, on=[col_chosen,"Gene"], how="outer")
297
+ result = dff_5.select([
298
+ pl.when((pl.col('len').is_not_null()) & (pl.col('total').is_not_null()))
299
+ .then(pl.col('len') / pl.col('total')*100)
300
+ .otherwise(None).alias("%"),
301
+ ])
302
+ result = result.with_columns(pl.col("%").fill_null(0))
303
+ dff_5[["percentage"]] = result[["%"]]
304
+ dff_5 = dff_5.select(pl.col(col_chosen,"Gene","percentage"))
305
+
306
+ # Final part to join the percentage expressed and mean expression levels
307
+ expression_means = expression_means.join(dff_5, on=[col_chosen,"Gene"], how="inner")
308
+
309
+ fig_scatter_db0_5 = px.scatter(data_frame=dff, x='X_umap-0', y='X_umap-1', color=s_chosen,
310
+ labels={'X_umap-0': 'umap1' , 'X_umap-1': 'umap2'},
311
+ hover_name=None, title="S-cycle gene:",template="seaborn")
312
+
313
+ fig_scatter_db0_6 = px.scatter(data_frame=dff, x='X_umap-0', y='X_umap-1', color=g2m_chosen,
314
+ labels={'X_umap-0': 'umap1' , 'X_umap-1': 'umap2'},
315
+ hover_name='condition', title="G2M-cycle gene:",template="seaborn")
316
+
317
+ fig_scatter_db0_7 = px.scatter(data_frame=dff, x='X_umap-0', y='X_umap-1', color="S_score",
318
+ labels={'X_umap-0': 'umap1' , 'X_umap-1': 'umap2'},
319
+ hover_name='condition', title="S score:",template="seaborn")
320
+
321
+ fig_scatter_db0_8 = px.scatter(data_frame=dff, x='X_umap-0', y='X_umap-1', color="G2M_score",
322
+ labels={'X_umap-0': 'umap1' , 'X_umap-1': 'umap2'},
323
+ hover_name='condition', title="G2M score:",template="seaborn")
324
+
325
+ # Sort values of custom in-between
326
+ dff = dff.sort(condition1_chosen)
327
+
328
+ fig_scatter_db0_9 = px.scatter(data_frame=dff, x='X_umap-0', y='X_umap-1', color=condition1_chosen,
329
+ labels={'X_umap-0': 'umap1' , 'X_umap-1': 'umap2'},
330
+ hover_name=None,hover_data = None, template="seaborn",category_orders=cat_ord)
331
+ fig_scatter_db0_9.update_traces(hoverinfo='none', hovertemplate=None)
332
+ fig_scatter_db0_9.update_layout(hovermode=False)
333
+
334
+ fig_scatter_db0_10 = px.scatter(data_frame=dff, x='X_umap-0', y='X_umap-1', color=condition2_chosen,
335
+ labels={'X_umap-0': 'umap1' , 'X_umap-1': 'umap2'},
336
+ hover_name='condition',template="seaborn")
337
+
338
+ fig_scatter_db0_11 = px.scatter(data_frame=dff, x=condition1_chosen, y=condition2_chosen, color=condition1_chosen,
339
+ #labels={'X_umap-0': 'umap1' , 'X_umap-1': 'umap2'},
340
+ hover_name='condition',template="seaborn",category_orders=cat_ord)
341
+
342
+ # Reorder categories on natural sorting or on the integrated cell state order of the paper
343
+ if col_chosen == "integrated_cell_states":
344
+ fig_scatter_db0_12 = px.scatter(data_frame=expression_means, x="Gene", y=col_chosen, color="Mean expression",
345
+ size="percentage", size_max = 20,
346
+ #labels={'X_umap-0': 'umap1' , 'X_umap-1': 'umap2'},
347
+ hover_name=col_chosen,template="seaborn",category_orders={col_chosen: natsorted(expression_means[col_chosen].unique())})
348
+ else:
349
+ fig_scatter_db0_12 = px.scatter(data_frame=expression_means, x="Gene", y=col_chosen, color="Mean expression",
350
+ size="percentage", size_max = 20,
351
+ #labels={'X_umap-0': 'umap1' , 'X_umap-1': 'umap2'},
352
+ hover_name=col_chosen,template="seaborn",category_orders={col_chosen: natsorted(expression_means[col_chosen].unique()),"Gene": condition3_chosen})
353
+
354
+ fig_violin_db02 = px.violin(data_frame=dff, x=condition1_chosen, y=condition2_chosen, box=True, points="all",
355
+ color=condition1_chosen, hover_name=condition1_chosen,template="seaborn",category_orders=cat_ord)
356
+
357
+
358
+ return fig_scatter_db0_5, fig_scatter_db0_6, fig_scatter_db0_7, fig_scatter_db0_8, fig_scatter_db0_9, fig_scatter_db0_10, fig_scatter_db0_11, fig_scatter_db0_12, fig_violin_db02
359
+ import polars as pl
360
+ import os
361
  pl.enable_string_cache(False)
362
 
363
  dash.register_page(__name__, location="sidebar")
 
462
  options=df.columns),
463
  html.Label("N Genes by Counts"),
464
  dcc.RangeSlider(
465
+ id='range-slider_db0-1',
466
  step=250,
467
  value=[min_value, max_value],
468
  marks={i: str(i) for i in range(min_value, max_value + 1, 250)},
469
  ),
470
+ dcc.Input(id='min-slider_db0-1', type='number', value=min_value, debounce=True),
471
+ dcc.Input(id='max-slider_db0-1', type='number', value=max_value, debounce=True),
472
  html.Label("Total Counts"),
473
  dcc.RangeSlider(
474
+ id='range-slider_db0-2',
475
  step=7500,
476
  value=[min_value_2, max_value_2],
477
  marks={i: str(i) for i in range(min_value_2, max_value_2 + 1, 7500)},
478
  ),
479
+ dcc.Input(id='min-slider_db0-2', type='number', value=min_value_2, debounce=True),
480
+ dcc.Input(id='max-slider_db0-2', type='number', value=max_value_2, debounce=True),
481
  html.Label("Percent Mitochondrial Genes"),
482
  dcc.RangeSlider(
483
+ id='range-slider_db0-3',
484
  step=5,
485
  min=0,
486
  max=100,
487
  value=[min_value_3, max_value_3],
488
  ),
489
+ dcc.Input(id='min-slider_db0-3', type='number', value=min_value_3, debounce=True),
490
+ dcc.Input(id='max-slider_db0-3', type='number', value=max_value_3, debounce=True),
491
  html.Div([
492
+ dcc.Graph(id='pie-graph_db0', figure={}, className='four columns',config=config_fig),
493
+ dcc.Graph(id='my-graph_db0', figure={}, clickData=None, hoverData=None,
494
  className='four columns',config=config_fig
495
  ),
496
+ dcc.Graph(id='scatter-plot_db0', figure={}, className='four columns',config=config_fig)
497
  ]),
498
  html.Div([
499
+ dcc.Graph(id='scatter-plot_db0-2', figure={}, className='four columns',config=config_fig)
500
  ]),
501
  html.Div([
502
+ dcc.Graph(id='scatter-plot_db0-3', figure={}, className='four columns',config=config_fig)
503
  ]),
504
  html.Div([
505
+ dcc.Graph(id='scatter-plot_db0-4', figure={}, className='four columns',config=config_fig)
506
  ]),
507
  ])
508
 
509
+ # Create the second tab content with scatter-plot_db0-5 and scatter-plot_db0-6
510
  tab2_content = html.Div([
511
  html.Div([
512
  html.Label("S-cycle genes"),
 
616
 
617
  ]),
618
  html.Div([
619
+ dcc.Graph(id='scatter-plot_db0-5', figure={}, className='three columns',config=config_fig)
620
  ]),
621
  html.Div([
622
+ dcc.Graph(id='scatter-plot_db0-6', figure={}, className='three columns',config=config_fig)
623
  ]),
624
  html.Div([
625
+ dcc.Graph(id='scatter-plot_db0-7', figure={}, className='three columns',config=config_fig)
626
  ]),
627
  html.Div([
628
+ dcc.Graph(id='scatter-plot_db0-8', figure={}, className='three columns',config=config_fig)
629
  ]),
630
  ])
631
 
632
+ # Create the second tab content with scatter-plot_db0-5 and scatter-plot_db0-6
633
  tab3_content = html.Div([
634
  html.Div([
635
  html.Label("UMAP condition 1"),
 
639
  dcc.Dropdown(id='dpdn6', value="n_genes_by_counts", multi=False,
640
  options=df.columns),
641
  html.Div([
642
+ dcc.Graph(id='scatter-plot_db0-9', figure={}, className='four columns',config=config_fig)
643
  ]),
644
  html.Div([
645
+ dcc.Graph(id='scatter-plot_db0-10', figure={}, className='four columns',config=config_fig)
646
  ]),
647
  html.Div([
648
+ dcc.Graph(id='scatter-plot_db0-11', figure={}, className='four columns',config=config_fig)
649
  ]),
650
  html.Div([
651
+ dcc.Graph(id='my-graph_db02', figure={}, clickData=None, hoverData=None,
652
  className='four columns',config=config_fig
653
  )
654
  ]),
655
  ]),
656
  ])
657
  # html.Div([
658
+ # dcc.Graph(id='scatter-plot_db0-12', figure={}, className='four columns',config=config_fig)
659
  # ]),
660
 
661
 
 
666
  options=df.columns),
667
  ]),
668
  html.Div([
669
+ dcc.Graph(id='scatter-plot_db0-12', figure={}, className='row',style={'width': '100vh', 'height': '90vh'}), # px)
670
  ]),
671
  ])
672
 
 
686
 
687
  # Define the circular callback
688
  @callback(
689
+ Output("min-slider_db0-1", "value"),
690
+ Output("max-slider_db0-1", "value"),
691
+ Output("min-slider_db0-2", "value"),
692
+ Output("max-slider_db0-2", "value"),
693
+ Output("min-slider_db0-3", "value"),
694
+ Output("max-slider_db0-3", "value"),
695
+ Input("min-slider_db0-1", "value"),
696
+ Input("max-slider_db0-1", "value"),
697
+ Input("min-slider_db0-2", "value"),
698
+ Input("max-slider_db0-2", "value"),
699
+ Input("min-slider_db0-3", "value"),
700
+ Input("max-slider_db0-3", "value"),
701
 
702
  )
703
  def circular_callback(min_1, max_1, min_2, max_2, min_3, max_3):
704
  return min_1, max_1, min_2, max_2, min_3, max_3
705
 
706
  @callback(
707
+ Output('range-slider_db0-1', 'value'),
708
+ Output('range-slider_db0-2', 'value'),
709
+ Output('range-slider_db0-3', 'value'),
710
+ Input('min-slider_db0-1', 'value'),
711
+ Input('max-slider_db0-1', 'value'),
712
+ Input('min-slider_db0-2', 'value'),
713
+ Input('max-slider_db0-2', 'value'),
714
+ Input('min-slider_db0-3', 'value'),
715
+ Input('max-slider_db0-3', 'value'),
716
 
717
  )
718
  def update_slider_values(min_1, max_1, min_2, max_2, min_3, max_3):
719
  return [min_1, max_1], [min_2, max_2], [min_3, max_3]
720
 
721
  @callback(
722
+ Output(component_id='my-graph_db0', component_property='figure'),
723
+ Output(component_id='pie-graph_db0', component_property='figure'),
724
+ Output(component_id='scatter-plot_db0', component_property='figure'),
725
+ Output(component_id='scatter-plot_db0-2', component_property='figure'),
726
+ Output(component_id='scatter-plot_db0-3', component_property='figure'),
727
+ Output(component_id='scatter-plot_db0-4', component_property='figure'), # Add this new scatter plot
728
+ Output(component_id='scatter-plot_db0-5', component_property='figure'),
729
+ Output(component_id='scatter-plot_db0-6', component_property='figure'),
730
+ Output(component_id='scatter-plot_db0-7', component_property='figure'),
731
+ Output(component_id='scatter-plot_db0-8', component_property='figure'),
732
+ Output(component_id='scatter-plot_db0-9', component_property='figure'),
733
+ Output(component_id='scatter-plot_db0-10', component_property='figure'),
734
+ Output(component_id='scatter-plot_db0-11', component_property='figure'),
735
+ Output(component_id='scatter-plot_db0-12', component_property='figure'),
736
+ Output(component_id='my-graph_db02', component_property='figure'),
737
  Input(component_id='dpdn2', component_property='value'),
738
  Input(component_id='dpdn3', component_property='value'),
739
  Input(component_id='dpdn4', component_property='value'),
740
  Input(component_id='dpdn5', component_property='value'),
741
  Input(component_id='dpdn6', component_property='value'),
742
  Input(component_id='dpdn7', component_property='value'),
743
+ Input(component_id='range-slider_db0-1', component_property='value'),
744
+ Input(component_id='range-slider_db0-2', component_property='value'),
745
+ Input(component_id='range-slider_db0-3', component_property='value'),
746
 
747
  )
748
 
 
764
  dff = dff.sort(col_chosen)
765
 
766
  # Plot figures
767
+ fig_violin_db0 = px.violin(data_frame=dff, x=col_chosen, y=col_features, box=True, points="all",
768
  color=col_chosen, hover_name=col_chosen,template="seaborn")
769
 
770
  # Cache commonly used subexpressions
 
819
  #expression_means = expression_means.select(["batch", "Gene", "Expression"] + condition3_chosen)
820
  category_counts = category_counts.sort(col_chosen)
821
 
822
+ fig_pie_db0 = px.pie(category_counts, values="normalized_count", names=col_chosen, labels=col_chosen, hole=.3, title=pie_title, template="seaborn")
823
 
824
  #labels = category_counts[col_chosen].to_list()
825
  #values = category_counts["normalized_count"].to_list()
826
 
827
  # Create the scatter plots
828
+ fig_scatter_db0 = px.scatter(data_frame=dff, x='X_umap-0', y='X_umap-1', color=col_chosen,
829
  labels={'X_umap-0': 'umap1' , 'X_umap-1': 'umap2'},
830
  hover_name='batch',template="seaborn")
831
 
832
+ fig_scatter_db0_2 = px.scatter(data_frame=dff, x='X_umap-0', y='X_umap-1', color=col_mt,
833
  labels={'X_umap-0': 'umap1' , 'X_umap-1': 'umap2'},
834
  hover_name='batch',template="seaborn")
835
 
836
+ fig_scatter_db0_3 = px.scatter(data_frame=dff, x='X_umap-0', y='X_umap-1', color=col_features,
837
  labels={'X_umap-0': 'umap1' , 'X_umap-1': 'umap2'},
838
  hover_name='batch',template="seaborn")
839
 
840
 
841
+ fig_scatter_db0_4 = px.scatter(data_frame=dff, x='X_umap-0', y='X_umap-1', color=col_counts,
842
  labels={'X_umap-0': 'umap1' , 'X_umap-1': 'umap2'},
843
  hover_name='batch',template="seaborn")
844
 
845
+ fig_scatter_db0_5 = px.scatter(data_frame=dff, x='X_umap-0', y='X_umap-1', color=s_chosen,
846
  labels={'X_umap-0': 'umap1' , 'X_umap-1': 'umap2'},
847
  hover_name='batch', title="S-cycle gene:",template="seaborn")
848
 
849
+ fig_scatter_db0_6 = px.scatter(data_frame=dff, x='X_umap-0', y='X_umap-1', color=g2m_chosen,
850
  labels={'X_umap-0': 'umap1' , 'X_umap-1': 'umap2'},
851
  hover_name='batch', title="G2M-cycle gene:",template="seaborn")
852
 
853
+ fig_scatter_db0_7 = px.scatter(data_frame=dff, x='X_umap-0', y='X_umap-1', color="S_score",
854
  labels={'X_umap-0': 'umap1' , 'X_umap-1': 'umap2'},
855
  hover_name='batch', title="S score:",template="seaborn")
856
 
857
+ fig_scatter_db0_8 = px.scatter(data_frame=dff, x='X_umap-0', y='X_umap-1', color="G2M_score",
858
  labels={'X_umap-0': 'umap1' , 'X_umap-1': 'umap2'},
859
  hover_name='batch', title="G2M score:",template="seaborn")
860
 
861
  # Sort values of custom in-between
862
  dff = dff.sort(condition1_chosen)
863
 
864
+ fig_scatter_db0_9 = px.scatter(data_frame=dff, x='X_umap-0', y='X_umap-1', color=condition1_chosen,
865
  labels={'X_umap-0': 'umap1' , 'X_umap-1': 'umap2'},
866
  hover_name='batch',template="seaborn")
867
 
868
+ fig_scatter_db0_10 = px.scatter(data_frame=dff, x='X_umap-0', y='X_umap-1', color=condition2_chosen,
869
  labels={'X_umap-0': 'umap1' , 'X_umap-1': 'umap2'},
870
  hover_name='batch',template="seaborn")
871
 
872
+ fig_scatter_db0_11 = px.scatter(data_frame=dff, x=condition1_chosen, y=condition2_chosen, color=condition1_chosen,
873
  #labels={'X_umap-0': 'umap1' , 'X_umap-1': 'umap2'},
874
  hover_name='batch',template="seaborn")
875
 
876
+ fig_scatter_db0_12 = px.scatter(data_frame=expression_means, x="Gene", y=col_chosen, color="Mean expression",
877
  size="percentage", size_max = 20,
878
  #labels={'X_umap-0': 'umap1' , 'X_umap-1': 'umap2'},
879
  hover_name=col_chosen,template="seaborn")
880
 
881
+ fig_violin_db02 = px.violin(data_frame=dff, x=condition1_chosen, y=condition2_chosen, box=True, points="all",
882
  color=condition1_chosen, hover_name=condition1_chosen,template="seaborn")
883
 
884
 
885
+ return fig_violin_db0, fig_pie_db0, fig_scatter_db0, fig_scatter_db0_2, fig_scatter_db0_3, fig_scatter_db0_4, fig_scatter_db0_5, fig_scatter_db0_6, fig_scatter_db0_7, fig_scatter_db0_8, fig_scatter_db0_9, fig_scatter_db0_10, fig_scatter_db0_11, fig_scatter_db0_12, fig_violin_db02
886
 
887
  # Set http://localhost:5000/ in web browser
888
  # Now create your regular FASTAPI application