微生物屋のノート

プログラミング・解析関連についてのノートです。

MacでPythonファイルを実行ファイルにする方法

最近のGoogle検索は、個人の検索履歴に引っ張られて適切な情報が出てこない。
そのせいかもしれないが、思っていた方法が見つからないし、ChatGPTに聞いても欲しい情報がでなかったので、メモしておきます。

動機

Windowsでは、Pythonファイルをテキストエディターではなく、Pythonから開くように設定することで、ダブルクリックで簡単に実行できる。

Macで同じことをやろうとしても、ファイルを開くアプリとしてPythonが見つからない。

Finderの「情報を見る」で、ファイルを開くアプリの選択可能

求めているのは、pyinstallerとかでの実行ファイル化というよりも、「編集可能なルーチンワークを行うプログラム」を必要最低限で作ることだった。

解決策

1. Pythonファイルの上部に、シェバンを記入。
これで実行するプログラムを指定するので、ここにはPythonのPathを記入。
`#!/usr/local/bin/python`

2. Pythonファイルの拡張子を消す。
例:exe.py を exeに変更

3. Terminalから、実行権限を付与
chmod +x exe

なぜか、exe.pyに実行権限を与えてもダブルクリックで起動できなかったが、この方法だと、実行ファイル化(ダブルクリックで起動)できる。

研究者ホームページ作成と移行のお知らせ

去年、1年間、会社員を経験して、アカデミアに戻ってきました。
宣伝を兼ねたホームページを作成し、このブログでの書いたものもまとめていこうと思います。

以下が、リンクです。
Fujita Hiroaki's Website

完全移行するかは、まだ考え中(ggplot関連のような小話はこっちという使い分け)ですが、できるだけDocumentsの中に、Rのはじめ方や、生物群集解析をまとめていこうかと思います。

ggplot の書式、特殊文字

ggplot2 内で、モデル式やR2 といった累乗の記号、ギリシャ文字を書きたいことが多々あると思います。

その場合は、expression 関数の例が多いと思うのですが(ggplot2でギリシャ文字や数式を表示したい - Qiita)、markdown や、文字コードを使っても色々かけます。

ggtext::element_markdown

markdown 形式で書くためのパッケージ・関数が、ggtext パッケージの element_markdown です。
Markdown theme elements • ggtext

使い方は、文字列を markdown 形式で書いて、theme で指定してやるだけです。
プロットエリア内は、geom_richtext を使います。
Improved Text Rendering Support for ggplot2 • ggtext

library(ggplot2)
library(ggtext)

g = ggplot()+
    geom_richtext(aes(x=1, y=1, label="*Hello*<br>world</br>"))+
    labs(x="*italic*", y="**bold**",
         title="square<sup>2</sup> subscript<sub>2</sub>")+
    theme(
      plot.title = element_markdown(),
      axis.title.x = element_markdown(),
      axis.title.y = element_markdown()
    )

plot(g)

自分が markdown に詳しくないのですが、どんな markdown でも対応しているわけではなさそうです。
書き方を調べるうえでは、Rmarkdownの書き方を参考にすれば、うまくいくことが多いです。

以下、element_markdown での書き方の例です。
順次更新していこうと思います。

斜体 *word*
<en>word<en/>
太字 **word**
上付き <sup>word<sup/>
下付き <sub>word<sub/>
下付き <sub>word<sub/>
アルファ(α)
斜体アルファ(α)
&alpha;
<i>&alpha;</i>
ベータ(β) \&beta;
<i>&beta;</i>
シータ(θ) \&theta;
<i>&theta;</i>

文字コード

「≧ (以上、大なりイコール)」などの特殊文字は、文字コードを使えば楽でした。
使い方は、uから始まる文字コード (u0020など)の前にバックスラッシュをつけるだけです。

library(ggplot2)
library(ggtext)

g = ggplot()+
    geom_richtext(aes(x=1, y=1, label="y = x <br> *P* \u2265 0.05"))
plot(g)


これの便利なところが、IMEパッドを開けば対応する文字コードがわかるので、いろんな文字をRで表示できそうです。

RStanインストールのメモ

Windows、R 4.2.3、Rtools42の環境下では以下のページに従えばうまくいった。
discourse.mc-stan.org

remove.packages(c("StanHeaders", "rstan"))
install.packages("StanHeaders", repos = c("https://mc-stan.org/r-packages/", getOption("repos")))
install.packages("rstan", repos = c("https://mc-stan.org/r-packages/", getOption("repos")))




ちなみに失敗例は

  1. 何も考えずにrstanをインストールして、stan関数を動かしたときは「collect2.exe: error: ld returned 1 exit status no DLL was created」とエラーが出た
  2. 1の解決のために、古いバージョン(rstan 2.19.xx)をインストールしても、同様のエラーが発生
  3. 公式にしたがって、以下のコマンドを実行
Sys.setenv(MAKEFLAGS = paste0("-j",parallel::detectCores()))
install.packages(c("StanHeaders","rstan"),type="source")

消えるはずの「Error in compileCode(f, code, language = language, verbose = verbose) : 」のエラーが出続ける。

最終的に、冒頭のページに従えば解決した。
開発中のパッケージバージョン(2.26.22)をインストールしたっぽい。

Visual studio codeのテーマを作ってみた

仕事の上でVisual studio codeをみんな使っていたので、自分も使ってみました。
しかし、テーマカラーの色で気に入ったものがなかったため、自分で作ってみました。

作ったからには人に見せたいと思ったので、テーマを置いてあるGithubのリンクを張っておきます。
GitHub - hiroakif93/VScode_theme: My visual studio code theme

使い方は、Githubからおとした「snow」フォルダを、「ホーム」ディレクトリにある「.vscode」フォルダ内の「extensions」フォルダに置くだけ(「.vscode」は隠しフォルダになってたので、コマンドラインからコピー)。

そしたら、VS code内の設定から変更できるようになります。



エディターは白のほうが好き(慣れてしまった)なのですが、他のテーマ見てたら白が強くてさすがに目が疲れたので、少しぼかしてるのが特徴です。
あと、白の要素を減らすためにターミナルは黒にしてみました。

名前の由来は、以下のGoogle Chromeのテーマを真似したからです。

https://chrome.google.com/webstore/detail/red-fox-snow-theme/cgaadipmojdihomphfmjphmelinpdalg

作るにあたっては以下のサイトを参考にさせていただきました。
atmarkit.itmedia.co.jp


構文ハイライトはこれからいじっていきたいと思います。



追記
2023/5/15
別のパソコンに落としてもうまくいかなかった。。。

ggplot2 で追加のscale_color / scale_fillを指定する方法

とても便利なのに、日本語サイトで見ないのでメモを兼ねて書きます。

よく ggplot2 を使っていると、geom_point と geom_bar で、違うcolor_scale を指定したいことがあると思います。また、色の指定の際に、連続値(continuous scale) と離散値(discrete scale)の両方を使うとエラーが出てしまいます。

それを解決してくれるのが以下のパッケージです。

eliocamp.github.io

使い方はとても簡単で、scale_color_,,, の後に、new_scale() を追加するだけです。


使用するパッケージを読みこみます

library(ggplot2)
library(ggnewscale) ## 新しくscaleを追加するためのパッケージ
library(tidyr) 

テストデータを作成。

site=10
sp=5

# サンプル×種の表
mat = matrix(runif(site*sp), nrow=site, ncol=sp,
             dimnames=list(paste('S', formatC(1:site,width=2,flag="0"), sep='_'), 
                           paste('Sp', formatC(1:sp,width=2,flag="0"), sep='_')))

# 環境データ
env = data.frame('Sample' = rownames(mat),
                 'Env1' = as.integer(runif(site, 0, 2)),
                 'Env2' = as.integer(runif(site, 0, 4)), 
                 row.names = rownames(mat))


# 2つの表を引っ付ける
df <- cbind(env, mat)

# ggplot2 を使うため、ロングフォーマットになおす。
lf <- gather(df, key, value, -c(1:ncol(env)))

バープロットの作成

bar_color <- c("firebrick", "skyblue3", "forestgreen", "darkorange", "aliceblue")

bar1 = ggplot(lf, aes(x=Sample))+
       geom_bar(aes(y=value, fill=key), stat='identity')+
       geom_point(aes(y=Env1, fill=Env1), 
                  shape=21, # fill を使いためpoint の形を変更
                  stroke=0.3# 枠線の太さ
                  )+
      scale_fill_manual(values=bar_color)
    


ここで、geom_point を環境の値によって色を変えたいのですが、連続値(環境変数)と離散値(種名)を入れているため、以下のようなエラーが出ます。

Error: Continuous value supplied to discrete scale


次に、new_scale 関数を使用します。

bar_color <- c("firebrick", "skyblue3", "forestgreen", "darkorange", "aliceblue")

bar1 = ggplot(lf, aes(x=Sample))+
       geom_bar(aes(y=value, fill=key), stat='identity')+
       scale_fill_manual(values=bar_color)+ ##             <- ここでバープロット用のscale_fill を指定
       ggnewscale::new_scale_fill()+        ##             <- geom_pointの前にnew_scale_fill を挟む
       geom_point(aes(y=Env1, fill=Env1), 
                  shape=21,
                  stroke=0.3
                  )+
       scale_fill_gradient2()              ##             <- geom_pointの用のscale_fill を指定
   

以下の図が作成できます。


離散値と連続値の色を指定できるようになるのは、とても便利ですね。
また、色以外の scale (scale_size、scale_shape)にも対応していそうです。

よくある分類群ごとの積み上げグラフ(バープロット)の作り方の例

研究室内で、「分類群ごとの積み上げグラフをどうやって作るか」という質問があったので簡単な作り方の例を紹介します。

(こういうやつ↓)
Networks Depicting the Fine-Scale Co-Occurrences of Fungi in Soil Horizons | PLOS ONE


用意するファイルは以下の3つです。

  • サンプル×種の表 (行がサンプル、列が種、中身は個体数情報など)
  • 分類群の情報 ( 行が分類群の最小単位、種でもいいしNGSデータならOTU・ASVです。列が最小単位の分類群の上位階層)
  • あれば環境データ(行がサンプル、列が環境データ)

テストデータです

site=10
sp=5

# サンプル×種の表
mat = matrix(runif(site*sp), nrow=site, ncol=sp,
             dimnames=list(paste('S', formatC(1:site,width=2,flag="0"), sep='_'), 
                           paste('Sp', formatC(1:sp,width=2,flag="0"), sep='_')))

# 分類群の情報
taxa = data.frame('Phylum' = formatC(as.integer(runif(sp, 0, 2)),width=2,flag="0"),
                  'Order' = formatC(as.integer(runif(sp, 0, 4)),width=2,flag="0"),
                  'Genus' = formatC(as.integer(runif(sp, 0, 8)),width=2,flag="0"), 
                  row.names = colnames(mat))
for(i in 1:ncol(taxa)){ taxa[,i] <- paste(colnames(taxa)[i], taxa[,i], sep='_')}

# 環境データ
env = data.frame('Sample' = rownames(mat),
                 'Env1' = as.integer(runif(site, 0, 2)),
                 'Env2' = as.integer(runif(site, 0, 4)), 
                 row.names = rownames(mat))

サンプル×種の表の列が、最小分類群単位になっているので、これを見てみたい分類群の階層で、足し合わせます。(例えば、Sp_01 から Sp_05 は、同じ Order_03 という目に入るので、それらを足してあげます)

ただし、これを行うのは、種数が多いと大変です。
なので、関数を用意しました。

# x がサンプル×種の表
# y が分類軍の情報
# taxaLabel がまとめたい分類群の名前
# function は足しわせるのに都合が悪い時用に、用意してあります。 

# 注意点は x のcolnames と y のrownamesが対応してある必要があります

Taxa.mat <- function(x, y, taxaLabel, func=function(x){sum(x)}){
    
    colnames(x) <- y[colnames(x), taxaLabel]
    
    summary <- do.call(cbind,
                       lapply(unique(colnames(x)), 
                              function(a){ num <- which(colnames(x)==a)
                              apply(as.matrix(x[,num]), 1, func)}) )
    
    colnames(summary) <- unique(colnames(x))
    summary
}

あとは、ggplot の geom_bar にかけてあげるだけできます。

library(ggplot2)
library(tidyr) 

merge.mat <- Taxa.mat(mat, taxa, 'Genus')
# ロングフォーマットになおす。その際に環境データをくっつける
lf <- gather(cbind(env, merge.mat), key, value, -c(1:ncol(env)))
head(lf)

# bar1 がただの積み上げ。geom_bar の引数のposition = 'fill を指定すると、100 % 積み上げグラフになります
bar1 = ggplot(lf)+
       geom_bar(aes(x=Sample, y=value, fill=key), stat='identity')
bar2 = ggplot(lf)+
       geom_bar(aes(x=Sample, y=value, fill=key), stat='identity', position='fill')

# x軸を環境データ(Env2 などにしたら、さらに環境でまとめられます)
bar3 = ggplot(lf)+
       geom_bar(aes(x=Env2, y=value, fill=key), stat='identity', position='fill')
左がbar1 の結果、右がbar2 の結果

x軸ラベルの重なりなどは、以前の記事を参考にしてもらえればと思います。
ggplot2 で、軸ラベルの重なりを防ぐ方法 - 微生物屋のノート


以上が一例になります。
この記事を書きながら、ggplot の段階で色分けする方法もあるなと気づいていしまったので、今回の記事はやりやすい方法を見つける参考にしていただければと思います。