ggpubr::ggarrangeでcommon.legend = TRUEにすると凡例のテーマがデフォルトになる

現象

ggpubrはggplot2をより手軽に扱うためのライブラリです.
ggpubr::ggarrange()は複数のグラフを並べるための関数で,各グラフの幅やレイアウトを簡単に操作することができます.

このとき,各グラフで同じ凡例を表示させるのは冗長ですので,引数 common.legend = TRUE を指定すると凡例をひとまとめにしてくれます.

[スクリプト]

library(ggplot2)
library(ggpubr)

g1 <- ggplot(data = iris, aes(x = Sepal.Length, y = Petal.Length, color = Species))
g1 <- g1 + geom_point()

g2 <- ggplot(data = iris, aes(x = Sepal.Length, y = Sepal.Width, color = Species))
g2 <- g2 + geom_point()

g <- ggarrange(g1, g2, nrow = 1, ncol = 2, common.legend = TRUE, legend = "right")
print(g)

[実行結果] f:id:data_tamago:20190916144207p:plain

非常に便利な関数なのですが,凡例がデフォルトのテーマで表示される仕様のようです. テーマを好みのものに変更している場合,思っていたものと違う見た目になってしまいます.

[スクリプト]

library(ggplot2)
library(ggthemes)
library(ggpubr)

# sample: background color of common legend is default:
g1 <- ggplot(data = iris, aes(x = Sepal.Length, y = Petal.Length, color = Species))
g1 <- g1 + geom_point()
g1 <- g1 + theme_solarized(light = FALSE)

g2 <- ggplot(data = iris, aes(x = Sepal.Length, y = Sepal.Width, color = Species))
g2 <- g2 + geom_point()
g2 <- g2 + theme_solarized(light = FALSE)

g <- ggarrange(g1, g2, nrow = 1, ncol = 2, common.legend = TRUE, legend = "right")
print(g)

[実行結果] f:id:data_tamago:20190916144736p:plain

凡例の上下が白くなってしまいます.

解決策

ggarrangeの出力に対して更にテーマを指定するだけでした.

[スクリプト]

g <- g + theme_solarized(light = FALSE)
print(g)

[実行結果] f:id:data_tamago:20190916144823p:plain

凡例周辺の枠線が若干怪しい(?)ものの,凡例にもテーマを適用できました.この簡単な操作に気付かずまた時間を溶かしてしまいました.

sklearnを使用するスクリプトをpyinstallerでexe化したら無限ループになった

現象

sklearnをimportして適当な文字列を表示するだけのスクリプトを, pyinstallerで実行可能ファイルにすることを考えます.
ubuntu,python3.6.9,sklearn==0.21.2で確認)

app.py

import sklearn

# ~処理~

print('HELLO sklearn!')
$ pyinstaller --onefile app.py

実行可能ファイルはデフォルトで ./dist 下に保存されます.
これを実行すると無限ループが始まります.

$ ./dist/app

実行結果

HELLO sklearn!
HELLO sklearn!
HELLO sklearn!
HELLO sklearn!
...

解決策

joblib(+おそらくsklearnも)のバージョンを下げることで解決しました.

  • joblib==0.11
  • scikit-learn==0.21.2

参考: sklearn/joblib spawns multiple copies when frozen on macOS
Macでも発生するようですが,Windowsでは大丈夫でした.

flaskアプリをexe化するとき発生したので,原因の特定が難しかったです.
無限ループに入ると「ポートが既に使用されている」エラーが表示されました.
そのため,最初は通信の問題だと思って調査して時間を溶かしてしまいました..