genomenet Claude Opus 4.5 commited on
Commit
46ad2bd
·
1 Parent(s): ad73274

Major UI improvements: interactive plots and better downloads

Browse files

Prediction Plot:
- Now uses interactive Plotly (zoom, pan, hover tooltips)
- CRISPR regions highlighted with shaded areas
- Hover shows exact position and score

Downloads (appear after analysis in collapsible accordion):
- PNG and PDF plot exports
- CSV file with all position/probability data
- Summary text file with results

Embeddings Tab:
- Downloads also in collapsible accordion
- Only visible after running analysis

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

Files changed (1) hide show
  1. app.py +131 -24
app.py CHANGED
@@ -63,8 +63,8 @@ EMBEDDING_CRISPR_EXAMPLE = """GACAGGTACAAGAAGGAGTATGCATCAATGTGGTCGTGTGGAACAAACGC
63
  EMBEDDING_RANDOM_EXAMPLE = """ATGCGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCT"""
64
 
65
 
66
- def create_prediction_plot(positions, probabilities, threshold=0.3):
67
- """Create a matplotlib figure showing the prediction curve."""
68
  fig, ax = plt.subplots(figsize=(12, 4))
69
 
70
  # Plot probability curve
@@ -92,6 +92,60 @@ def create_prediction_plot(positions, probabilities, threshold=0.3):
92
  return fig
93
 
94
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
  def create_embedding_heatmap(embedding, title="Sequence Embedding", cols=30):
96
  """Create a heatmap visualization of the embedding vector."""
97
  embedding = np.array(embedding)
@@ -543,23 +597,62 @@ def create_interactive_state_plot(embeddings, n_clusters=8, stride=100, use_3d=F
543
 
544
  def predict(sequence: str, stride: int = 100, threshold: float = 0.3):
545
  """Predict CRISPR array probability for each position."""
 
 
 
546
  sequence = strip_fasta_header(sequence.strip())
547
 
548
  is_valid, error = validate_sequence(sequence)
549
  if not is_valid:
550
- return None, f"**Error**: {error}", None, None, None
551
 
552
  result = predict_sequence(sequence, stride=stride, aggregation="mean")
553
 
554
- # Create plot
555
- fig = create_prediction_plot(result.positions, result.probabilities, threshold)
556
 
557
- # Save for download
558
- png_path, pdf_path = save_figure_to_file(fig, "crispr_prediction")
559
 
560
- # Detect regions
561
- regions = detect_crispr_regions(sequence, threshold=threshold, min_length=100, stride=stride)
 
 
562
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
563
  summary = f"""## Results
564
 
565
  | Metric | Value |
@@ -576,7 +669,7 @@ def predict(sequence: str, stride: int = 100, threshold: float = 0.3):
576
  for r in regions:
577
  summary += f"- **Region {r['region_id']}**: positions {r['start']:,}-{r['end']:,} ({r['length']} bp), score: {r['mean_score']:.3f}\n"
578
 
579
- return fig, summary, regions, png_path, pdf_path
580
 
581
 
582
  def detect(sequence: str, threshold: float = 0.3, min_length: int = 160):
@@ -721,7 +814,7 @@ Detect CRISPR arrays in DNA sequences using a BERT-based deep learning model (43
721
  """)
722
 
723
  with gr.Tab("Predict & Visualize"):
724
- gr.Markdown("Paste a DNA sequence to get per-position CRISPR probability scores with visualization.")
725
  with gr.Row():
726
  with gr.Column(scale=1):
727
  seq_input = gr.Textbox(
@@ -752,18 +845,28 @@ Detect CRISPR arrays in DNA sequences using a BERT-based deep learning model (43
752
  lambda: NON_CRISPR_EXAMPLE, outputs=seq_input
753
  )
754
  result_summary = gr.Markdown()
755
- gr.Markdown("### Download Plot")
756
- with gr.Row():
757
- pred_download_png = gr.File(label="PNG", interactive=False)
758
- pred_download_pdf = gr.File(label="PDF", interactive=False)
 
 
 
 
 
759
  with gr.Column(scale=2):
760
- plot_output = gr.Plot(label="CRISPR Score Profile")
761
  regions_output = gr.JSON(label="Detected Regions", visible=False)
762
 
 
 
 
 
 
763
  predict_btn.click(
764
- predict,
765
  inputs=[seq_input, stride_input, threshold_input],
766
- outputs=[plot_output, result_summary, regions_output, pred_download_png, pred_download_pdf]
767
  )
768
 
769
  with gr.Tab("Embeddings"):
@@ -809,10 +912,10 @@ Visualize how the model's internal representation changes across the sequence. T
809
  - Downstream: 2364-2964 bp (random)
810
  """)
811
  embed_summary = gr.Markdown()
812
- gr.Markdown("### Download Plot")
813
- with gr.Row():
814
- download_png = gr.File(label="PNG", interactive=False)
815
- download_pdf = gr.File(label="PDF", interactive=False)
816
  with gr.Column(scale=2):
817
  embed_plot = gr.Plot(label="Embedding Visualization (Interactive)")
818
 
@@ -823,10 +926,14 @@ Visualize how the model's internal representation changes across the sequence. T
823
  outputs=[use_3d]
824
  )
825
 
 
 
 
 
826
  embed_btn.click(
827
- get_embedding,
828
  inputs=[embed_seq, embed_mode, use_3d],
829
- outputs=[embed_plot, embed_summary, download_png, download_pdf]
830
  )
831
 
832
  with gr.Tab("About"):
 
63
  EMBEDDING_RANDOM_EXAMPLE = """ATGCGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTGATCGATCGATCGATCGATCGTAGCTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCT"""
64
 
65
 
66
+ def create_prediction_plot(positions, probabilities, threshold=0.3, regions=None):
67
+ """Create a matplotlib figure showing the prediction curve (for PNG/PDF export)."""
68
  fig, ax = plt.subplots(figsize=(12, 4))
69
 
70
  # Plot probability curve
 
92
  return fig
93
 
94
 
95
+ def create_interactive_prediction_plot(positions, probabilities, threshold=0.3, regions=None):
96
+ """Create an interactive Plotly figure showing the prediction curve."""
97
+ fig = go.Figure()
98
+
99
+ # Main probability curve with fill
100
+ fig.add_trace(go.Scatter(
101
+ x=positions,
102
+ y=probabilities,
103
+ mode='lines',
104
+ name='CRISPR Score',
105
+ line=dict(color='royalblue', width=1),
106
+ fill='tozeroy',
107
+ fillcolor='rgba(65, 105, 225, 0.2)',
108
+ hovertemplate='Position: %{x:,} bp<br>Score: %{y:.3f}<extra></extra>'
109
+ ))
110
+
111
+ # Add threshold line
112
+ fig.add_hline(
113
+ y=threshold,
114
+ line_dash="dash",
115
+ line_color="red",
116
+ annotation_text=f"Threshold ({threshold})",
117
+ annotation_position="top right"
118
+ )
119
+
120
+ # Highlight detected CRISPR regions
121
+ if regions:
122
+ for r in regions:
123
+ fig.add_vrect(
124
+ x0=r['start'], x1=r['end'],
125
+ fillcolor="rgba(255, 0, 0, 0.15)",
126
+ layer="below",
127
+ line_width=0,
128
+ annotation_text=f"Region {r['region_id']}",
129
+ annotation_position="top left",
130
+ annotation_font_size=10
131
+ )
132
+
133
+ fig.update_layout(
134
+ title=dict(text='CRISPR Array Detection Score', font=dict(size=16)),
135
+ xaxis_title='Position (bp)',
136
+ yaxis_title='CRISPR Probability',
137
+ yaxis=dict(range=[0, 1], gridcolor='lightgray'),
138
+ xaxis=dict(range=[0, max(positions) if positions else 1000], gridcolor='lightgray'),
139
+ hovermode='x unified',
140
+ showlegend=True,
141
+ legend=dict(yanchor="top", y=0.99, xanchor="right", x=0.99),
142
+ height=400,
143
+ plot_bgcolor='white'
144
+ )
145
+
146
+ return fig
147
+
148
+
149
  def create_embedding_heatmap(embedding, title="Sequence Embedding", cols=30):
150
  """Create a heatmap visualization of the embedding vector."""
151
  embedding = np.array(embedding)
 
597
 
598
  def predict(sequence: str, stride: int = 100, threshold: float = 0.3):
599
  """Predict CRISPR array probability for each position."""
600
+ import tempfile
601
+ import csv
602
+
603
  sequence = strip_fasta_header(sequence.strip())
604
 
605
  is_valid, error = validate_sequence(sequence)
606
  if not is_valid:
607
+ return None, f"**Error**: {error}", None, None, None, None, None
608
 
609
  result = predict_sequence(sequence, stride=stride, aggregation="mean")
610
 
611
+ # Detect regions first (needed for plot annotations)
612
+ regions = detect_crispr_regions(sequence, threshold=threshold, min_length=100, stride=stride)
613
 
614
+ # Create interactive Plotly plot
615
+ fig = create_interactive_prediction_plot(result.positions, result.probabilities, threshold, regions)
616
 
617
+ # Create static matplotlib plot for PNG/PDF export
618
+ static_fig = create_prediction_plot(result.positions, result.probabilities, threshold, regions)
619
+ png_path, pdf_path = save_figure_to_file(static_fig, "crispr_prediction")
620
+ plt.close(static_fig)
621
 
622
+ # Create CSV with prediction data
623
+ temp_dir = tempfile.gettempdir()
624
+ csv_path = os.path.join(temp_dir, "crispr_predictions.csv")
625
+ with open(csv_path, 'w', newline='') as f:
626
+ writer = csv.writer(f)
627
+ writer.writerow(['position', 'probability', 'above_threshold'])
628
+ for pos, prob in zip(result.positions, result.probabilities):
629
+ writer.writerow([pos, f"{prob:.4f}", prob >= threshold])
630
+
631
+ # Create summary text file
632
+ summary_path = os.path.join(temp_dir, "crispr_summary.txt")
633
+ summary_text = f"""CRISPR Array Detection Summary
634
+ ==============================
635
+
636
+ Sequence length: {result.sequence_length:,} bp
637
+ Windows processed: {result.num_windows}
638
+ Stride: {stride} bp
639
+ Threshold: {threshold}
640
+
641
+ Overall score: {result.overall_score:.4f}
642
+ Max score: {max(result.probabilities):.4f}
643
+ Min score: {min(result.probabilities):.4f}
644
+
645
+ Detected CRISPR Regions: {len(regions)}
646
+ """
647
+ if regions:
648
+ summary_text += "\nRegion Details:\n"
649
+ for r in regions:
650
+ summary_text += f" Region {r['region_id']}: {r['start']:,}-{r['end']:,} bp ({r['length']} bp), mean score: {r['mean_score']:.3f}\n"
651
+
652
+ with open(summary_path, 'w') as f:
653
+ f.write(summary_text)
654
+
655
+ # Markdown summary for display
656
  summary = f"""## Results
657
 
658
  | Metric | Value |
 
669
  for r in regions:
670
  summary += f"- **Region {r['region_id']}**: positions {r['start']:,}-{r['end']:,} ({r['length']} bp), score: {r['mean_score']:.3f}\n"
671
 
672
+ return fig, summary, regions, png_path, pdf_path, csv_path, summary_path
673
 
674
 
675
  def detect(sequence: str, threshold: float = 0.3, min_length: int = 160):
 
814
  """)
815
 
816
  with gr.Tab("Predict & Visualize"):
817
+ gr.Markdown("Paste a DNA sequence to get per-position CRISPR probability scores with interactive visualization.")
818
  with gr.Row():
819
  with gr.Column(scale=1):
820
  seq_input = gr.Textbox(
 
845
  lambda: NON_CRISPR_EXAMPLE, outputs=seq_input
846
  )
847
  result_summary = gr.Markdown()
848
+ with gr.Accordion("Downloads", open=False, visible=False) as download_accordion:
849
+ gr.Markdown("**Plot exports:**")
850
+ with gr.Row():
851
+ pred_download_png = gr.File(label="PNG", interactive=False)
852
+ pred_download_pdf = gr.File(label="PDF", interactive=False)
853
+ gr.Markdown("**Data exports:**")
854
+ with gr.Row():
855
+ pred_download_csv = gr.File(label="Predictions (CSV)", interactive=False)
856
+ pred_download_summary = gr.File(label="Summary (TXT)", interactive=False)
857
  with gr.Column(scale=2):
858
+ plot_output = gr.Plot(label="CRISPR Score Profile (Interactive)")
859
  regions_output = gr.JSON(label="Detected Regions", visible=False)
860
 
861
+ def predict_and_show_downloads(*args):
862
+ results = predict(*args)
863
+ # Return results plus visibility update for accordion
864
+ return results + (gr.update(visible=True),)
865
+
866
  predict_btn.click(
867
+ predict_and_show_downloads,
868
  inputs=[seq_input, stride_input, threshold_input],
869
+ outputs=[plot_output, result_summary, regions_output, pred_download_png, pred_download_pdf, pred_download_csv, pred_download_summary, download_accordion]
870
  )
871
 
872
  with gr.Tab("Embeddings"):
 
912
  - Downstream: 2364-2964 bp (random)
913
  """)
914
  embed_summary = gr.Markdown()
915
+ with gr.Accordion("Downloads", open=False, visible=False) as embed_download_accordion:
916
+ with gr.Row():
917
+ download_png = gr.File(label="PNG", interactive=False)
918
+ download_pdf = gr.File(label="PDF", interactive=False)
919
  with gr.Column(scale=2):
920
  embed_plot = gr.Plot(label="Embedding Visualization (Interactive)")
921
 
 
926
  outputs=[use_3d]
927
  )
928
 
929
+ def embed_and_show_downloads(*args):
930
+ results = get_embedding(*args)
931
+ return results + (gr.update(visible=True),)
932
+
933
  embed_btn.click(
934
+ embed_and_show_downloads,
935
  inputs=[embed_seq, embed_mode, use_3d],
936
+ outputs=[embed_plot, embed_summary, download_png, download_pdf, embed_download_accordion]
937
  )
938
 
939
  with gr.Tab("About"):