Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import scanpy as sc | |
| import matplotlib.pyplot as plt | |
| import pandas as pd | |
| import numpy as np | |
| from anndata import AnnData | |
| import io | |
| import warnings | |
| # Suppress some scanpy warnings for cleaner output | |
| warnings.filterwarnings('ignore') | |
| def process_h5ad_file(file_obj): | |
| """ | |
| Process uploaded h5ad file and generate visualizations | |
| """ | |
| try: | |
| # Read the h5ad file | |
| adata = sc.read_h5ad(file_obj.name) | |
| # Basic preprocessing | |
| sc.pp.normalize_total(adata, target_sum=1e4) | |
| sc.pp.log1p(adata) | |
| sc.pp.highly_variable_genes(adata, min_mean=0.0125, max_mean=3, min_disp=0.5) | |
| adata = adata[:, adata.var.highly_variable] | |
| sc.pp.scale(adata, max_value=10) | |
| # Run PCA and compute neighbors | |
| sc.tl.pca(adata, svd_solver='arpack') | |
| sc.pp.neighbors(adata, n_pcs=10, n_neighbors=10) | |
| # Run clustering and UMAP | |
| sc.tl.leiden(adata) | |
| sc.tl.umap(adata) | |
| # Get available categorical columns for coloring | |
| categorical_cols = [col for col in adata.obs.columns if adata.obs[col].dtype.name == 'category'] | |
| # Create basic info string | |
| info_text = f""" | |
| Dataset Info: | |
| - Number of cells: {adata.n_obs:,} | |
| - Number of genes: {adata.n_vars:,} | |
| - Available metadata columns: {', '.join(adata.obs.columns)} | |
| """ | |
| # Create UMAP plot | |
| fig_umap, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5)) | |
| # Default UMAP colored by leiden clusters | |
| sc.pl.umap(adata, color='leiden', ax=ax1, show=False) | |
| ax1.set_title('UMAP (Leiden Clusters)') | |
| # If cell_type exists, use it for second plot, otherwise use first categorical column | |
| color_by = 'cell_type' if 'cell_type' in categorical_cols else categorical_cols[0] if len(categorical_cols) > 0 else 'leiden' | |
| sc.pl.umap(adata, color=color_by, ax=ax2, show=False) | |
| ax2.set_title(f'UMAP ({color_by})') | |
| plt.tight_layout() | |
| umap_buffer = io.BytesIO() | |
| plt.savefig(umap_buffer, format='png', dpi=100) | |
| plt.close() | |
| # Create heatmap of top variable genes | |
| sc.pl.highly_variable_genes(adata, show=False) | |
| heatmap_buffer = io.BytesIO() | |
| plt.savefig(heatmap_buffer, format='png', dpi=100) | |
| plt.close() | |
| # Create dropdown options for coloring | |
| dropdown_options = ['leiden'] + categorical_cols | |
| return ( | |
| info_text, | |
| umap_buffer, | |
| heatmap_buffer, | |
| gr.Dropdown.update(choices=dropdown_options, value='leiden') | |
| ) | |
| except Exception as e: | |
| error_msg = f"Error processing file: {str(e)}" | |
| return error_msg, None, None, None | |
| def update_umap_plot(file_obj, color_by): | |
| """ | |
| Update UMAP plot based on selected coloring variable | |
| """ | |
| try: | |
| if file_obj is None: | |
| return None | |
| adata = sc.read_h5ad(file_obj.name) | |
| # Check if the selected column exists | |
| if color_by not in adata.obs.columns and color_by != 'leiden': | |
| raise ValueError(f"Column '{color_by}' not found in dataset") | |
| fig, ax = plt.subplots(figsize=(6, 5)) | |
| sc.pl.umap(adata, color=color_by, ax=ax, show=False) | |
| ax.set_title(f'UMAP ({color_by})') | |
| plt.tight_layout() | |
| buffer = io.BytesIO() | |
| plt.savefig(buffer, format='png', dpi=100) | |
| plt.close() | |
| return buffer | |
| except Exception as e: | |
| error_msg = f"Error updating plot: {str(e)}" | |
| return error_msg | |
| # Define the Gradio interface | |
| with gr.Blocks(title="Single-cell RNA-seq Visualizer") as app: | |
| gr.Markdown("# Single-cell RNA-seq Visualizer") | |
| gr.Markdown("Upload your `.h5ad` file to visualize single-cell RNA-seq data") | |
| with gr.Row(): | |
| with gr.Column(): | |
| file_input = gr.File(label="Upload .h5ad file", file_types=[".h5ad"]) | |
| submit_btn = gr.Button("Process File") | |
| # Dropdown for selecting coloring variable (will be updated after file upload) | |
| color_dropdown = gr.Dropdown( | |
| label="Color UMAP by", | |
| choices=[], | |
| interactive=True | |
| ) | |
| # Info text box | |
| info_output = gr.Textbox(label="Dataset Information") | |
| with gr.Column(): | |
| # Output for UMAP plots | |
| umap_output = gr.Image(label="UMAP Plots", type="pil") | |
| # Output for heatmap | |
| heatmap_output = gr.Image(label="Top Variable Genes", type="pil") | |
| # Output for updated UMAP | |
| updated_umap_output = gr.Image(label="Custom UMAP", type="pil") | |
| # Event handlers | |
| submit_btn.click( | |
| fn=process_h5ad_file, | |
| inputs=file_input, | |
| outputs=[info_output, umap_output, heatmap_output, color_dropdown] | |
| ) | |
| color_dropdown.change( | |
| fn=update_umap_plot, | |
| inputs=[file_input, color_dropdown], | |
| outputs=updated_umap_output | |
| ) | |
| # Run the app | |
| if __name__ == "__main__": | |
| app.launch() |