據(jù)分析環(huán)境搭建與完整流程實戰(zhàn))
如果你正在做單細胞測序數(shù)據(jù)分析大概率會遇到這樣一個尷尬的場景別人的教程里代碼一行接一行跑得飛快圖也漂亮到了自己電腦上光是搭建環(huán)境、組織代碼、調試參數(shù)就已經(jīng)耗掉大半天。更常見的情況是你已經(jīng)在用 Python 寫分析腳本但每個步驟的中間結果只能靠 print 和 matplotlib 硬看改一個過濾閾值就要把整個流程重新跑一遍。這個問題的根源往往不是你不會寫代碼而是缺少一個合適的交互式分析環(huán)境。Jupyter Notebook 恰恰就是為這種“邊寫邊看、邊調邊想”的場景設計的。而對于單細胞數(shù)據(jù)分析Python 生態(tài)里最主流的框架 Scanpy它的官方教程、社區(qū)案例幾乎全部基于 Jupyter Notebook 展開??梢赃@么說Jupyter Notebook 是 Scanpy 的最佳運行載體而 Scanpy 是 Jupyter Notebook 最能發(fā)揮價值的分析場景之一。這篇文章不是簡單羅列 Notebook 的快捷鍵也不是把 Scanpy 的文檔翻譯一遍。我會從一個完整的單細胞數(shù)據(jù)分析流程出發(fā)把 Jupyter Notebook 和 Scanpy 結合起來講清楚你為什么要用 Notebook 做單細胞分析、環(huán)境和依賴怎么裝、Windows 下常見的空白頁面問題怎么解決、如何在 PyCharm 里使用 Notebook、以及 Scanpy 從數(shù)據(jù)讀取到聚類注釋的完整代碼怎么落地。讀完這篇文章你應該能獨立搭建一套“Jupyter Notebook Scanpy”的單細胞數(shù)據(jù)分析環(huán)境并跑通一條標準分析流程。1. 這篇文章真正要解決的問題很多初學者對 Jupyter Notebook 和 Scanpy 的關系存在誤解。有些人覺得 Notebook 只是一個“高級記事本”用 PyCharm 寫腳本也能替代有些人則認為 Scanpy 只是 Seurat 的 Python 替代品換個工具而已。這兩種理解都過于簡單了。先看 Jupyter Notebook 解決了什么問題。在傳統(tǒng)腳本開發(fā)模式下你寫一個analysis.py從頭跑到尾中間某個步驟出錯就要修完從頭再來。單細胞數(shù)據(jù)分析恰恰是最不適合這種模式的工作之一它高度依賴人工判斷每個過濾閾值都需要反復調整每次調整都要配合可視化結果觀察效果分析過程本身就是一條需要不斷回溯、修正的探索鏈。Notebook 把代碼拆成一個一個 Cell你可以只運行其中一個 Cell看到結果再決定下一步怎么改。這種交互方式的改變直接決定了單細胞分析的效率。再看 Scanpy 解決了什么問題。單細胞轉錄組數(shù)據(jù)本質上是一個巨大的稀疏矩陣動輒數(shù)萬基因、數(shù)萬細胞。傳統(tǒng)的數(shù)據(jù)處理工具很難支撐這種規(guī)模。Scanpy 基于 AnnData 數(shù)據(jù)結構底層借助 NumPy、SciPy、pandas 等科學計算庫實現(xiàn)高效運算同時把數(shù)據(jù)過濾、歸一化、降維、聚類、差異表達、可視化整合成一套統(tǒng)一 API。更重要的一點是Scanpy 的數(shù)據(jù)結構設計非常符合單細胞分析的習慣它把表達矩陣、細胞元信息、基因元信息、降維結果放在同一個對象里分析過程中的每一步結果都可以被記錄下來。如果把單細胞數(shù)據(jù)分析比作做菜Jupyter Notebook 是廚房操作臺Scanpy 是完整的廚具套裝。操作臺決定了你下廚的節(jié)奏和效率廚具決定你能做出口味多穩(wěn)定的菜品。很多人只關注廚具卻低估了操作臺的重要性。這篇文章適合以下讀者剛接觸單細胞數(shù)據(jù)分析想用 Python 生態(tài)完成分析但不知道如何下手。已經(jīng)裝了 Anaconda 或 Jupyter Notebook但遇到啟動空白、環(huán)境混亂、不知道怎么在 PyCharm 里使用等問題。會跑 Scanpy 基礎教程但不清楚每一步的輸入輸出是什么也不知道分析結果如何解讀。想從 R 語言的 Seurat 遷移到 Python 生態(tài)需要理解兩種工具的核心差異。2. 為什么單細胞數(shù)據(jù)分析需要 Jupyter Notebook2.1 分析流程的探索性質單細胞數(shù)據(jù)分析不是一條直線的 pipeline。以標準的 10x Genomics 數(shù)據(jù)處理為例你需要依次完成質控過濾、歸一化、高變基因篩選、PCA 降維、UMAP/tSNE 可視化、聚類、marker 基因鑒定、細胞類型注釋。表面上看這是一個固定順序但實際操作中每步都可能回退。比如你完成了聚類發(fā)現(xiàn)某個 cluster 可能是雙細胞或低質量細胞就需要回到質控步驟調整過濾閾值重新跑下游分析。這種“前進兩步、后退一步”的工作模式用傳統(tǒng)腳本會非常痛苦。你不得不注釋掉大段代碼或者用全局變量控制流程開關。而在 Notebook 中每個步驟天然是一個 Cell你可以隨時修改任意一個 Cell 并重新運行后面的分析結果會基于新結果繼續(xù)。這種靈活性不是腳本編輯器能提供的。2.2 可視化和代碼的無縫結合單細胞分析的每個重要決策都依賴可視化結果。過濾閾值選多少要看基因數(shù)分布圖和高變基因圖PCA 選多少個主成分要看方差貢獻率圖聚類分辨率選多少要看 UMAP 圖上 cluster 的分布是否合理。Jupyter Notebook 的 Cell 輸出可以直接內(nèi)嵌 matplotlib、scanpy 等庫生成的圖像而且支持 Retina 高清顯示。你不需要像傳統(tǒng)腳本那樣把圖片保存成文件再打開也不需要頻繁切換窗口。代碼和對應的圖放在同一個 Cell 里分析過程的可讀性和可復現(xiàn)性都大幅提升。2.3 逐步構建分析的中間產(chǎn)物單細胞分析有一個很實用的技巧把每一個中間結果保存下來方便后續(xù)回溯。比如過濾后的數(shù)據(jù)存一份filtered.h5ad聚類后的數(shù)據(jù)存一份clustered.h5ad。在 Notebook 中你可以在每個關鍵節(jié)點用adata.write()保存結果發(fā)現(xiàn)問題時用sc.read_h5ad()快速恢復。數(shù)據(jù)和代碼在同一個界面中交替出現(xiàn)這種體驗是腳本編輯器很難帶來的。3. Jupyter Notebook 核心概念與基礎操作3.1 Jupyter Notebook 和 JupyterLab 到底有什么區(qū)別很多初學者會在這兩個名字之間糾結。簡單說JupyterLab 是 Jupyter Notebook 的下一代交互界面。但這不代表你必須遷移到 JupyterLab。兩者的關系用一張表可以看得很清楚對比維度Jupyter NotebookJupyterLab界面風格單文檔界面一個 Notebook 占據(jù)主區(qū)域多文檔工作臺可同時打開 Notebook、終端、文本編輯器文件管理功能較簡單能瀏覽文件操作有限完整文件瀏覽器支持拖拽、多標簽頁、分欄布局擴展能力支持 extensions但生態(tài)相對簡單插件體系更強大支持自定義布局上手難度更簡單適合初學者稍復雜但功能上限更高運行內(nèi)核一致底層都是 Jupyter Kernel一致從實際使用角度看如果你只是跑 Scanpy 分析兩者功能差異不大。我的建議是下載 Anaconda 后自帶的是經(jīng)典 Notebook 界面可以先從這里開始。當你覺得需要在同一個瀏覽器頁面里同時查看代碼、終端和文檔時再切換 JupyterLab 也不遲。不要在環(huán)境配置上過度糾結核心是跑通分析流程。3.2 Notebook 的 Cell 運行機制Jupyter Notebook 的基本單元是 Cell主要有兩種類型Code Cell 和 Markdown Cell。Code Cell 用來寫 Python 代碼運行后會把輸出顯示在 Cell 下方。這里有一個非常重要的機制Cell 之間共享同一個內(nèi)核Kernel。也就是說你在第一個 Cell 里定義了一個變量后面的 Cell 里可以直接使用它。這種全局命名空間的設計既方便又危險。方便在于你可以把步驟拆開危險在于如果你不按順序運行 Cell或者修改了前面的 Cell 沒有重新運行后續(xù)結果可能基于舊的變量狀態(tài)。Markdown Cell 用來寫說明文字支持 Markdown 語法也可以插入 LaTeX 數(shù)學公式。在單細胞分析中強烈建議在每一步分析前用 Markdown Cell 記錄你的判斷依據(jù)。比如“這里選擇過濾 200 個基因以下的細胞是因為根據(jù) violin plot這批細胞的基因數(shù)分布最低點在 200 附近”。這種記錄對后續(xù)復現(xiàn)和論文方法部分寫作非常有價值。3.3 Kernel 的作用與重啟Kernel 是 Notebook 背后的 Python 解釋器進程。當你點擊運行按鈕時代碼被發(fā)送到 Kernel 執(zhí)行。理解 Kernel 至少幫到你三個場景第一當變量狀態(tài)混亂時你可以通過“Kernel → Restart Run All”把內(nèi)核重啟按順序重新執(zhí)行所有 Cell。這一步能解決大量“為什么這個變量不存在”的問題。第二安裝新包后如果 Notebook 中import報錯 ModuleNotFoundError通常需要重啟 Kernel 才能加載新安裝的包。第三當你打開一個舊 Notebook 文件時如果使用的是 PyCharm 或 VS Code 的 Notebook 支持也要注意選擇正確的 Kernel 環(huán)境否則會因為 Python 解釋器不一致而出現(xiàn)找不到包的問題。3.4 Notebook 文件格式 .ipynbNotebook 文件的后綴是.ipynb本質是一個 JSON 文件。這個格式的好處是方便 Git 版本控制和平臺遷移壞處是如果文件較大打開會變慢如果有大量輸出圖像文件體積可能膨脹到幾十 MB。建議在分析中定期清理輸出Cell → Current Outputs → Clear保存比較干凈的版本到 Git 倉庫。對于數(shù)據(jù)文件如h5ad不要放進 Git而是使用獨立的數(shù)據(jù)存儲路徑。4. Jupyter Notebook 環(huán)境搭建與常見問題4.1 通過 Anaconda 安裝 Jupyter Notebook對于絕大多數(shù)單細胞數(shù)據(jù)分析場景推薦使用 Anaconda。Anaconda 不僅包含 Jupyter Notebook還預裝了 NumPy、SciPy、pandas、matplotlib 等科學計算核心庫能省去很多依賴問題。安裝完成后Windows 用戶可以在開始菜單找到Anaconda Prompt打開后執(zhí)行jupyter notebook運行后終端會輸出類似這樣的信息[I 2024-01-01 10:00:00.123] Serving notebooks from local directory: C:\Users\... [I 2024-01-01 10:00:00.456] Jupyter Server is running at: http://localhost:8888/tree?tokenabcdef...默認情況下Jupyter 會在http://localhost:8888啟動并自動打開默認瀏覽器。4.2 創(chuàng)建獨立的 Conda 環(huán)境我要特別強調一個工程實踐不要直接在 base 環(huán)境里安裝 Scanpy。單細胞分析涉及大量依賴包版本沖突概率很高。推薦為每個項目創(chuàng)建獨立環(huán)境conda create -n scanpy python3.9 conda activate scanpy pip install jupyter notebook pip install scanpy python -m ipykernel install --user --name scanpy --display-name Python (scanpy)注意第四條命令的作用把當前 conda 環(huán)境注冊為 Jupyter 可用的 Kernel。如果你跳過這一步即使在終端里激活了scanpy環(huán)境在 Notebook 里新建文件時仍然只能選擇默認的 Python 環(huán)境無法import scanpy。4.3 在 PyCharm 中使用 Jupyter NotebookPyCharm 專業(yè)版原生支持 Jupyter Notebook社區(qū)版也可以使用。如果你使用的是專業(yè)版最直接的方式是用 PyCharm 打開.ipynb文件PyCharm 會調用它內(nèi)置的 Notebook 編輯器。在編輯器的右上角可以選擇 Kernel選擇你在第 4.2 步注冊的scanpy環(huán)境即可。如果使用的是 PyCharm 社區(qū)版或者你的項目不是以.ipynb文件為核心可以換個思路在 PyCharm 的 Terminal 里啟動 Jupyter Notebook然后通過瀏覽器訪問localhost:8888照樣能打開 Notebook。這樣相當于把 PyCharm 當作終端和代碼編輯器把 Jupyter 當作分析界面二者互補。4.4 Windows 下 Jupyter Notebook 打開后空白的排查這是一個非常高頻的問題值得單獨寫一節(jié)。如果你在 Windows 上運行jupyter notebook后瀏覽器打開頁面完全空白請按以下順序排查。第一步看瀏覽器控制臺。按 F12 打開開發(fā)者工具切到 Console 標簽頁如果有紅色報錯大多是 JavaScript 資源加載失敗。第二步更換瀏覽器測試。很多情況下是當前瀏覽器與 Jupyter 前端不兼容或者瀏覽器緩存了舊的靜態(tài)資源。換到 Edge、Chrome、Firefox 任一瀏覽器嘗試通常能定位問題。第三步清空瀏覽器緩存和 Cookie特別是localhost:8888相關的緩存。第四步檢查端口沖突。如果8888端口被其他程序占用Jupyter 會自動更換端口這時終端里顯示的 URL 會變化。你要使用終端輸出的最新 URL而不是手動輸入的舊地址。第五步檢查是否存在代理或網(wǎng)絡加速軟件干擾本地請求。這種情況在 Windows 上并不少見關閉代理工具后重試即可。如果以上都沒解決可以在終端中強制指定瀏覽器打開 Jupyter命令如下。# 在 Jupyter 配置中指定瀏覽器Windows 系統(tǒng) jupyter notebook --no-browser然后手動復制終端中顯示的完整地址包含 token 的那一長串到 Chrome 或 Edge 中打開。4.5 如何更換 Jupyter Notebook 的默認瀏覽器有一些讀者希望 Jupyter 不要自動打開舊版 IE 或某個不常用的瀏覽器。可以通過修改 Jupyter 配置文件來解決。先生成配置文件jupyter notebook --generate-config然后打開生成的jupyter_notebook_config.py找到類似# c.NotebookApp.browser的位置設置為你的目標瀏覽器路徑。以 Chrome 為例在 Windows 下可以這樣改寫import webbrowser webbrowser.register(chrome, None, webbrowser.GenericBrowser(C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe)) c.NotebookApp.browser chrome修改后保存重新啟動jupyter notebook就會自動用 Chrome 打開。5. Scanpy 核心概念從數(shù)據(jù)格式到分析流程5.1 AnnData理解 Scanpy 的基石Scanpy 的所有分析都圍繞一個核心數(shù)據(jù)結構AnnData。這個名字是“Annotated Data”的縮寫。理解 AnnData 的設計思路就理解了 Scanpy 的設計思路。AnnData 可以理解為一條數(shù)據(jù)總線上掛載了多個組件。它的核心字段包括字段作用類比X表達矩陣行為細胞列為基因一張行×列的數(shù)字表格obs細胞observation的元信息如樣本來源、批次、細胞類型注釋每一行細胞的“身份證”var基因variable的元信息如基因名、是否高變基因每一列基因的“說明書”obsm細胞的降維坐標如 PCA、UMAP 結果細胞的“投影坐標”varm基因的降維坐標如基因在 PCA 上的載荷基因的“投影坐標”uns非結構化元數(shù)據(jù)如參數(shù)記錄、顏色設置備注信息在實際編碼中你最常見的操作模式是先讀取數(shù)據(jù)得到adata然后用adata.obs訪問細胞信息用adata.var訪問基因信息用adata.obsm[X_pca]訪問降維結果。分析過程中產(chǎn)生的每一步新結果都會被掛載到adata上。這種設計讓中間結果不會丟失也不需要在多個變量之間手動傳遞數(shù)據(jù)。5.2 Scanpy 標準分析流程說明書從數(shù)據(jù)到生物學發(fā)現(xiàn)Scanpy 的標準流程可以概括為七個步驟。這里先給一個宏觀視圖后面用代碼具體實現(xiàn)。第一步數(shù)據(jù)讀取與質量控制。讀取表達矩陣計算每個細胞的基因數(shù)和線粒體基因比例根據(jù)閾值過濾低質量細胞和低表達基因。第二步歸一化與對數(shù)化。消除測序深度差異使細胞間可比。第三步高變基因篩選。找出在細胞間表達差異最顯著的基因減少后續(xù)計算量。第四步PCA 降維。將高維表達矩陣壓縮到數(shù)十個主成分。第五步鄰里圖構建與 UMAP/tSNE 降維?;?PCA 結果構建細胞之間的鄰居關系再用 UMAP 可視化為二維平面。第六步聚類。使用 Leiden 算法識別細胞群。第七步marker 基因與細胞類型注釋。對每個 cluster 做差異表達分析找到特征基因根據(jù)已知 marker 基因判斷細胞類型。5.3 Scanpy 與 Seurat 的核心差異對于從 R 生態(tài)轉過來的讀者這里有必要做一個對比。Seurat 是 R 語言里最主流的單細胞分析包Scanpy 是 Python 生態(tài)的對應物。兩者在分析思路上非常相似因為底層都是相同的統(tǒng)計學方法。但差異在于第一Scanpy 可以無縫銜接 Python 的深度學習生態(tài)。如果你想用 scVI、scANVI 等深度學習模型做批次校正或數(shù)據(jù)整合Python 生態(tài)中可以直接調用。而在 R 中整合這些模型往往需要經(jīng)過中間格式轉換。第二Scanpy 的可擴展性更好。對于數(shù)百萬細胞級別的超大數(shù)據(jù)集Scanpy 支持基于anndata的分塊處理可以配合scanpy.external中的工具處理大型數(shù)據(jù)。第三Seurat 在 R 社區(qū)中擁有更多現(xiàn)成的可視化修飾包而 Scanpy 的繪圖風格更簡潔定制需要手動改 matplotlib 參數(shù)。這不代表 Scanpy 比 Seurat 好或者差。更合理的判斷是如果你想在 Python 生態(tài)中做單細胞分析或者需要后續(xù)接深度學習模型Scanpy 是繞不開的選擇。6. Scanpy 完整分析流程示例下面進入核心實操部分。我會使用 Scanpy 內(nèi)置的 PBMC 3K 數(shù)據(jù)集來演示完整流程。這個數(shù)據(jù)集來自 10x Genomics包含約 2700 個外周血單核細胞是 Scanpy 文檔中的經(jīng)典示例數(shù)據(jù)。6.1 環(huán)境準備與數(shù)據(jù)讀取進入 Jupyter Notebook新建一個 Python 文件先導入必要的庫。import numpy as np import pandas as pd import scanpy as sc import matplotlib.pyplot as plt # 設置畫圖參數(shù)讓圖像在 Notebook 中清晰顯示 sc.settings.set_figure_params(dpi100, frameonFalse, figsize(5, 5)) sc.settings.verbosity 3 # 輸出詳細日志然后讀取 PBMC 3K 數(shù)據(jù)。如果沒有聯(lián)網(wǎng)也可以使用sc.datasets.pbmc68k_reduced()讀取一個更小的測試數(shù)據(jù)。adata sc.datasets.pbmc3k() print(adata)輸出的類型信息AnnData object with n_obs × n_vars 2700 × 32738 var: gene_symbols這說明數(shù)據(jù)包含 2700 個細胞、32738 個基因。6.2 質量控制與過濾單細胞數(shù)據(jù)質量控制非常關鍵直接決定下游分析質量。我們計算三個核心指標每個細胞表達的基因數(shù)、每個細胞的總計數(shù)UMI 數(shù)、線粒體基因比例。這里需要解釋一下線粒體基因比例高通常意味著細胞狀態(tài)不佳可能是細胞破裂導致線粒體 RNA 泄漏也可能是凋亡信號。PBMC 數(shù)據(jù)中我們使用人類線粒體基因前綴MT-。# 計算線粒體基因比例 adata.var[mt] adata.var_names.str.startswith(MT-) sc.pp.calculate_qc_metrics(adata, qc_vars[mt], percent_topNone, log1pFalse, inplaceTrue)此時adata.obs中新增了n_genes_by_counts、total_counts、pct_counts_mt等列。我們先用小提琴圖查看分布。sc.pl.violin(adata, [n_genes_by_counts, total_counts, pct_counts_mt], multi_panelTrue)根據(jù)常見經(jīng)驗PBMC 數(shù)據(jù)通常過濾掉基因數(shù)少于 200 的細胞基因數(shù)大于 2500 的細胞可能是雙細胞線粒體基因比例高于 5% 的細胞可能是低質量細胞。但不同實驗數(shù)據(jù)閾值會變化需要結合 violin plot 調整。sc.pp.filter_cells(adata, min_genes200) sc.pp.filter_cells(adata, max_genes2500) adata adata[adata.obs.pct_counts_mt 5, :]這里還有一個容易被忽略的步驟過濾基因。幾乎所有細胞都不表達的基因沒有分析價值反而增加計算量。sc.pp.filter_genes(adata, min_cells3)執(zhí)行后可以打印數(shù)據(jù)形狀確認過濾效果。print(adata)6.3 歸一化、對數(shù)化與高變基因質控后需要進行數(shù)據(jù)標準化消除測序深度差異。sc.pp.normalize_total(adata, target_sum1e4) sc.pp.log1p(adata)normalize_total將每個細胞的總計數(shù)歸一化到target_sumlog1p對數(shù)據(jù)做log(x1)變換使數(shù)據(jù)分布更接近高斯分布滿足后續(xù)統(tǒng)計方法的假設。接下來篩選高變基因。這里需要理解它的意義單細胞數(shù)據(jù)有數(shù)萬個基因但大部分基因在不同細胞間表達差異不大。高變基因篩選能保留信息量最大的基因顯著降低后續(xù) PCA 和聚類計算量。sc.pp.highly_variable_genes(adata, min_mean0.0125, max_mean3, min_disp0.5) sc.pl.highly_variable_genes(adata)然后把表達矩陣精簡為只保留高變基因。注意這不是簡單切掉數(shù)據(jù)而是把非高變基因保留下來的做法只是后續(xù) PCA 只用高變基因。adata.raw adata adata adata[:, adata.var.highly_variable]這里有一個細節(jié)值得注意adata.raw adata保存了原始全部基因的表達矩陣供后續(xù) marker gene 可視化使用。6.4 PCA 降維PCA主成分分析可以把高維的基因表達空間壓縮為少數(shù)幾個主成分。在 Scanpy 中只需要一行代碼sc.tl.pca(adata, svd_solverarpack) sc.pl.pca_variance_ratio(adata, n_pcs50)pca_variance_ratio圖展示了每個主成分解釋的方差比例。通常選擇曲線拐點處的主成分數(shù)但也常見直接取前 20 或前 30 個。對于 PBMC 3K前 15 到 20 個主成分通常足夠。6.5 鄰里圖構建與 UMAP 可視化單細胞聚類的核心在于構建細胞之間的相似性網(wǎng)絡。先基于 PCA 結果計算細胞的 k 近鄰圖然后用 Leiden 算法找聚類。sc.pp.neighbors(adata, n_neighbors10, n_pcs15) sc.tl.umap(adata) sc.pl.umap(adata, colorleiden)先運行聚類因為 UMAP 上色需要聚類標簽。完整代碼是sc.tl.leiden(adata, resolution0.5) sc.pl.umap(adata, color[leiden])這里resolution控制聚類數(shù)量。分辨率越低聚成的類越少分辨率越高聚成的類越多。PBMC 數(shù)據(jù)一般取0.5到1.0之間需要根據(jù) UMAP 圖上 cluster 的分離程度調整。6.6 聚類與 marker 基因分析聚類完成后每個細胞都被分配了一個 cluster 標簽存在adata.obs[leiden]中。接下來要對每個 cluster 做差異表達分析找到 marker 基因。sc.tl.rank_genes_groups(adata, leiden, methodwilcoxon) sc.pl.rank_genes_groups(adata, n_genes20, shareyFalse)然后用sc.tl.marker_gene_overlap或查文獻確定每個 cluster 的細胞類型。PBMC 數(shù)據(jù)常見的 cell type 有 T 細胞CD3D、B 細胞MS4A1、NK 細胞NKG7、單核細胞LYZ等。可以通過sc.pl.dotplot來驗證。marker_genes { T cell: [CD3D, CD3E], B cell: [MS4A1, CD79A], NK cell: [NKG7, GNLY], Monocyte: [LYZ, CD14], } sc.pl.dotplot(adata, marker_genes, groupbyleiden)根據(jù) marker 基因的表達模式可以把 cluster 重命名并賦值給adata.obs[cell_type]然后重新在 UMAP 上可視化。6.7 保存與讀取分析結果分析結束時及時保存結果。adata.write(pbmc3k_analysis.h5ad)以后可以隨時讀取adata_read sc.read_h5ad(pbmc3k_analysis.h5ad)7. 運行結果與效果驗證7.1 怎么判斷你的分析“跑通了”很多初學者以為代碼不報錯就是分析完成這是誤解。跑通的標準應該是每個關鍵輸出都符合數(shù)據(jù)本身的生物學特征。判斷質控是否合理要看過濾后的細胞數(shù)是否在合理范圍。如果過濾后細胞數(shù)不足原來的 50%說明閾值可能過嚴需要回到 violin plot 重新觀察分布。判斷降維效果要看 UMAP 圖上是否有明顯的分離結構而不是一團顏色混雜的散點。判斷聚類效果要看 cluster 數(shù)量是否過多或過少正常 PBMC 數(shù)據(jù)通常在 5 到 13 個 cluster 之間。7.2 預期輸出示例當你依次運行第 6 節(jié)的代碼預期會看到sc.pl.violin輸出三張小提琴圖展示質控指標分布過濾后曲線右移。sc.pl.highly_variable_genes輸出一張散點圖高變基因高亮顯示。sc.pl.pca_variance_ratio輸出方差貢獻率曲線前 20 個主成分占比逐步下降。sc.pl.umap輸出 UMAP 圖不同 cluster 以不同顏色區(qū)分圖上有清晰的細胞群聚團。sc.pl.rank_genes_groups輸出每個 cluster 的 top 基因列表可用于確定細胞類型。7.3 失敗后第一步看哪里運行失敗時先看錯誤信息最后一行找到是哪個函數(shù)出的問題。常見錯誤有三類第一ModuleNotFoundError。這說明缺少依賴包或者你啟動的 Kernel 與安裝包的環(huán)境不一致。解決方式是檢查 Kernel 選擇然后在正確的環(huán)境中pip install。第二MemoryError。單細胞數(shù)據(jù)較大時常見解決方式是減少參與計算的基因數(shù)或換用更大內(nèi)存的機器。第三ValueError通常是因為輸入數(shù)據(jù)維度不符合函數(shù)要求。例如在未運行sc.pp.neighbors前調用sc.tl.umap會報找不到鄰里圖。8. Scanpy 與 Jupyter Notebook 常見問題排查問題現(xiàn)象可能原因排查方式解決方案Jupyter Notebook 打開頁面空白瀏覽器緩存、代理、靜態(tài)資源加載失敗打開 F12 查看 Console 報錯換 Chrome/Edge 測試關閉代理清緩存強制指定瀏覽器啟動使用帶 token 的完整 URLNotebook 中 import scanpy 報錯Kernel 環(huán)境與安裝環(huán)境不一致運行!which python查看解釋器路徑檢查 Kernel 列表在正確 conda 環(huán)境注冊 ipykernel或重新選擇 KernelScanpy 運行報ValueError上游步驟未執(zhí)行或數(shù)據(jù)過濾后維度異常逐 Cell 按順序運行使用adata打印確認形狀用Kernel → Restart Run All按順序重跑聚類結果明顯不合理主成分數(shù)選擇不當或過濾閾值不準確查看 PCA 方差貢獻率圖檢查過濾前后細胞數(shù)調整n_pcs參數(shù)回到 QC 步驟重新調閾值UMAP 圖上所有點擠在一起鄰居數(shù)過小或沒有正確執(zhí)行 PCA 和 neighbors檢查 PCA 是否成功查看n_neighbors設置適當增大n_neighbors確保使用高變基因做 PCA保存的 h5ad 文件過大保存了過多中間結果和原始矩陣檢查adata.uns與adata.raw大小清理不必要字段用adata adata[:, adata.var.highly_variable]瘦身后保存或刪除uns中的冗余信息9. 最佳實踐與工程建議9.1 Notebook 分析代碼的組織規(guī)范把分析過程分成邏輯清晰的 Cell順序執(zhí)行不要隨意跳轉。建議格式如下Cell 1導入庫與全局設置。Cell 2定義文件路徑和參數(shù)常量。Cell 3讀取數(shù)據(jù)與初步查看。Cell 4質控指標計算與可視化。Cell 5過濾。Cell 6歸一化、對數(shù)化、高變基因。Cell 7PCA。Cell 8鄰里圖、UMAP、聚類。Cell 9marker 基因與注釋。Cell 10保存結果。每一個關鍵決策點用 Markdown Cell 寫明理由。如果你要在論文中報告分析流程這部分文字可以直接修改為方法部分的內(nèi)容。9.2 依賴管理和可復現(xiàn)性強烈建議在項目目錄中維護requirements.txt或environment.yml。當你完成分析將環(huán)境導出pip freeze requirements.txt或者用 conda 導出conda env export environment.yml這樣同事或未來的你自己可以一鍵重建分析環(huán)境避免出現(xiàn)“換臺電腦跑不了”的問題。9.3 數(shù)據(jù)管理與版本控制不要將.h5ad數(shù)據(jù)文件提交到 Git 倉庫。建議的結構是project/ ├── data/ # 原始數(shù)據(jù)和中間數(shù)據(jù)不進 Git ├── notebook/ # .ipynb 文件進 Git ├── scripts/ # 可復用的 .py 工具函數(shù) ├── results/ # 輸出圖表和表格 └── environment.yml # 環(huán)境鎖文件9.4 謹慎使用inplaceTrue參數(shù)Scanpy 的很多函數(shù)提供了inplaceTrue參數(shù)默認在原對象上直接修改。這在 Notebook 分析中很便捷但要注意一旦執(zhí)行了覆蓋式修改再想回到上一步可能要重新從磁盤讀取數(shù)據(jù)。建議在修改數(shù)據(jù)的步驟上先復制一份對象或者保留原始數(shù)據(jù)為raw。9.5 調參與記錄的平衡單細胞分析允許反復調參數(shù)但不要只調不記。每改一個關鍵參數(shù)建議在 Markdown Cell 里記錄為何要這樣改以及前后效果差異。很多分析報告最終寫不出來不是因為數(shù)據(jù)不好而是因為中間過程沒有記錄。10. 總結與后續(xù)學習方向這篇內(nèi)容從 Jupyter Notebook 的運行機制講到 Scanpy 的完整單細胞分析流程核心是想幫助你建立一套統(tǒng)一的分析框架用 Notebook 承載探索性分析用 Scanpy 完成科學計算用規(guī)范的文件組織保證可復現(xiàn)。如果你剛入門建議先把環(huán)境搭好用 PBMC 3K 數(shù)據(jù)完整跑通上面的代碼對每一步的輸出有一個直觀印象。不要急著在自己的 10x 數(shù)據(jù)上跑完整流程因為不同數(shù)據(jù)集的質控特征差異很大沒有經(jīng)驗時容易把下游分析帶偏。接下來值得深入的方向有幾個批次效應校正Harmony、scVI、細胞類型自動注釋SingleR、CellTypist 或基于 marker 數(shù)據(jù)庫的注釋工具、軌跡分析用于發(fā)育相關研究、以及多組學數(shù)據(jù)整合。這些方向都建立在今天這套基礎流程之上把基礎打牢后再逐步擴展。最后給一個比較實用的建議把第 6 節(jié)的代碼整理成一個模板 notebook連同常用的 QC 閾值、marker 基因列表一起保存在本地。每次拿到新數(shù)據(jù)先在這個模板上跑一遍再根據(jù)數(shù)據(jù)特征調整細節(jié)。這是把“會跑教程”變成“會分析真實數(shù)據(jù)”最有效的一步。