julia で、flowcytometry のデータを plot する
julia で、flowcytometry のデータを plot してみましょう。 julia の速さがあれば、flowcytometry の解析も、基本的な解析ができます。
読み込みは、julia native であれば、FileIO.jl + FCSFiles が julia 1.0 でも動きます。 この方法では、julia の dictionary 形式で、データを読み込んでくれます。 dictionary を Array に変換する方法は、 別のブログ に記載してありますので、ご参照下さい。 生の FSC データは log や biexpornential への変換が必要になります。 読み込みから、このあたりの操作は、別の機会に記載させて頂きます。
今回は、簡便性のため、正規化された疑似データを plot することにします。 plot の方法は、業界標準の FlowJo の Dot, Pseudocolor, Contour の3種の plot を表現することにします。
まず、パッケージの読み込みと、正規化された疑似データを作ります。 速度の面等では、Plots ですが、Contour が不安定です。 Contour には、PyPlot を使うことにします。
using Plots, PyCall , PyPlot using KernelDensity using Distributions using StatsBase @pyimport seaborn as sns data = vcat( rand(Normal(),10000,2), rand(Normal(3,0.8),10000,2), rand(Normal(-2,2),10000,2).+[0 2], rand(TDist(10),1000,2) )[rand(1:31000,100000) ,:]; xdata = data[:,1]; ydata = data[:,2];
散布図 (Dot) の描画
まずは Dot を描きましょう。
Plots.plot(data[:,1],data[:,2], t=:scatter, markersize = 0.1, c="black")
ざっと、こんな具合です。初回は時間がかかります。
Pseudocolor
Plots に関する限りは、恐らく FlowJo の Pseudocolor に相当する histogram2d が最も使いやすそうです。
clibrary(:colorcet) Plots.histogram2d(data[:,1],data[:,2],nbins=200, c=:rainbow)
さすがに FlowJo は売り物なので、もう少し見栄えする気がします。
デフォルトの色も捨て難いです。
Contour
いわゆる等高線グラフであるところの Contour は、かなり骨が折れます。 FlowJo 流だと、一番外の等高線から外れた点を plot しないといけません。 等高線だけなら、seaborn の kdeplot() で描くことができます。 ここに、一番外の等高線から外れた点を選んで scatter しないといけません。 一番外の等高線は、KernelDensity.jl で、おおよそ計算できます。
ik = InterpKDE(kde(data)) function xy_ex(xdata,ydata, ik) xy_pdf = zeros(Float64, length(xdata)) for i in 1:length(xdata) xy_pdf[i] = pdf(ik, xdata[i], ydata[i]) end return xy_pdf end xy_ex_data = xy_ex(xdata,ydata, ik) xy_bool = xy_ex_data.< maximum(xy_ex_data)/30 - 0.0005
下は、描画のための関数です。
# サンプリング数を減らして描画する関数 function counterplot(xdata::Array{Float64,1}, ydata::Array{Float64,1}, xy_bool::BitArray{1}, n_sample::Int64) select_rows = rand(1:length(xdata), n_sample) sns.kdeplot(xdata[select_rows], ydata[select_rows], n_levels=30 , cbar=true , cmap=:inferno) sns.scatterplot(xdata[xy_bool], ydata[xy_bool], s=10, color="black") end # 全部描く関数 function counterplot_all(xdata, ydata, xy_bool) sns.kdeplot(xdata, ydata, n_levels=30 , cbar=true , cmap=:inferno) sns.scatterplot(xdata[xy_bool], ydata[xy_bool], s=10, color="black") end
ここまでが下準備です。 10^5 個描画すると、かなり時間がかかります。
julia> @time counterplot_all(xdata, ydata, xy_bool) 32.639432 seconds (190 allocations: 76.484 KiB) PyObject
さすがに30秒は、つらいので、1万個くらい選んで描画にします。
julia> @time counterplot(xdata, ydata, xy_bool, 10000) 2.076948 seconds (198 allocations: 311.125 KiB) PyObject
この位なら実用域ですね。
せっかくだから Makie.jl で Flowcytometry の疑似データを3次元プロットしてみよう。に3次元疑似データのプロットを載せました。
おしまい。