rna-visualizer / app.py
Ayesha003's picture
Update app.py
fa3bea9 verified
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()