まずは蝋の翼から。

学んだことを書きながら確認・整理するためのメモブログ。こういうことなのかな?といったことをふわっと書いたりしていますが、理解が浅いゆえに的はずれなことも多々あると思うのでツッコミ歓迎

ggplot2覚書④ 軸について

引き続き「Rグラフィッククックブック」。

過去記事は以下。

ggplot2覚書① 棒グラフ - まずは蝋の翼から。

ggplot2覚書② 散布図 - まずは蝋の翼から。

ggplot2覚書③ 注釈(解釈補助) - まずは蝋の翼から。

軸と目盛りの設定

theme(axis.text = ...

axis.textで軸目盛りのテキスト(数値やカテゴリカル変数など)となる。 axis.text.xでx軸、axis.text.yでy軸に対しておこなえる。

element_blank()を指定すると非表示にできる

g1 <- ggplot(PlantGrowth, aes(x=group, y=weight)) + 
  geom_boxplot()  

g2 <- ggplot(PlantGrowth, aes(x=group, y=weight)) + 
  geom_boxplot()  +
  theme(axis.text.x = element_blank())

g1 | g2

f:id:chito_ng:20190222183141p:plain

element_text(angle=xx, hjust=xx, vjust=xx, color= xxx, size= xxx, face=xxx))で設定の指定ができる。

  • angleは角度
  • hjustは0:右揃え、0.5:中央、1:左揃え、で水平位置
  • vjustは、0:上揃え、0.5:中央、1:下揃え、で垂直位置
  • colorは色
  • sizeは大きさ
  • faceはフォント
g1 <- ggplot(PlantGrowth, aes(x=group, y=weight)) +
  geom_boxplot() + 
  scale_x_discrete(breaks=c("ctrl", "trt1", "trt2"), labels=c("Control", "Treatment 1", "Treatment 2")) 

g2 <- ggplot(PlantGrowth, aes(x=group, y=weight)) +
  geom_boxplot() + 
  scale_x_discrete(breaks=c("ctrl", "trt1", "trt2"), labels=c("Control", "Treatment 1", "Treatment 2")) +
  theme(axis.text.x = element_text(angle=90, hjust=1, vjust=.5))

g1 | g2

f:id:chito_ng:20190222183549p:plain

labs(軸タイトル)

軸タイトルの中身の設定ができる。
xlab, ylabでそれぞれ設定できるがlabsで軸タイトルをx,yまとめて設定できる。
また、title = ...でグラフタイトルの設定もできる。

library(gcookbook)

ggplot(heightweight, aes(x=ageYear, y=heightIn, colour=sex)) +
  geom_point() +
  labs(x = "Age in years", y = "Height in inches")

f:id:chito_ng:20190222184300p:plain

theme(axis.title = ...

軸タイトルの設定ができる。下記ではelement_blankで軸タイトルを無くしている。

ggplot(PlantGrowth, aes(x=group, y=weight)) + 
  geom_boxplot() +
  theme(axis.title.x=element_blank())

f:id:chito_ng:20190222185637p:plain

scale_x_log10(軸の対数変換)

軸のスケールを対数変換するにはscale_x_log10, scale_y_log10を使う。

library(MASS) # データセットの読み込み 

g1 <- ggplot(Animals, aes(x=body, y=brain, label=rownames(Animals))) + 
  geom_text(size=3)

日付データの使用

Date, datetimeを用いた場合、軸設定が他とはやや異なる。 例えば、連続値の場合はscale_x_continuousだったが、日付データではscale_x_dateを用いた指定となる。

# economicsの一部を取り出す 
econ <- subset(economics, date >= as.Date("1992-05-01") & date < as.Date("1993-06-01"))

# 目盛を指定しない基本プロット 
p <- ggplot(econ, aes(x=date, y=psavert)) + geom_line()

# Dateクラスのベクトルを使って目盛位置を指定する。byで間隔の指定もできる。
datebreaks <- seq(as.Date("1992-06-01"), as.Date("1993-06-01"), by="2 month")

p + scale_x_date(breaks=datebreaks) + #間隔をdatebreaks変数で指定
  theme(axis.text.x = element_text(angle=30, hjust=1))

f:id:chito_ng:20190222192405p:plain

表示間隔は上記のようにbreaksオプションに対してbyで2ヶ月刻みに生成したDateクラスベクトルを指定する以外に、date_breaksオプションで直接間隔の指定もできる。また、date_labelsでフォーマットの指定もできる。

p + scale_x_date(date_breaks = '1 month', date_labels = '%y-%m-%d') + #1ヶ月刻み、yy-mm-dd
  theme(axis.text.x = element_text(angle=30, hjust=1)) 

f:id:chito_ng:20190222193124p:plain

並び替え

カテゴリカル変数軸の並び替え

下記の図をいい感じに並び替えたい。現在はデフォルトのアルファベット順になっている。 なお、並び替えのデフォルトはデータ型によって決まり、ファクタならばlevelで決まる。

library(gcookbook) # データセットの読み込み
tophit <- tophitters2001[1:25, ] # tophitters2001データセットから上位25名を抽出する 

ggplot(tophit, aes(x=avg, y=name)) + 
  geom_point()

f:id:chito_ng:20190217165327p:plain

1つの基準での並び替え

limitsに指定したベクトル順で表示される。

library(patchwork)

g1 <- ggplot(PlantGrowth, aes(x=group, y=weight)) +
  geom_boxplot() +
  scale_x_discrete(limits=c("ctrl","trt2","trt1"))

g2 <- ggplot(PlantGrowth, aes(x=group, y=weight)) +
  geom_boxplot() +
  scale_x_discrete(limits=c("trt2","ctrl","trt1"))

g1 | g2

f:id:chito_ng:20190221094659p:plain

また、直接ベクトルを指定するのではなく変数を指定することもできる。また、limitsにrev(levels(...))を指定することで順序を逆転させることもできる。

library(patchwork)

g1 <- ggplot(PlantGrowth, aes(x=group, y=weight)) + 
  geom_boxplot() + 
  coord_flip() + 
  scale_x_discrete(limits=rev(levels(PlantGrowth$group)))

g2 <- ggplot(PlantGrowth, aes(x=group, y=weight)) + 
  geom_boxplot() + 
  coord_flip() 

g1 | g2

複数基準での並び替え

reorder関数は1つの基準でしか並び替えができない。そのため、orderでlevelを作成し、そのlevelをプロットするデータに設定する。

yをnameからreorder(name, avg)に変更する。
reorder関数は第一引数に対して第二引数を基準にlevelを変更する(並び替える)。

ggplot(tophit, aes(x=avg, y=reorder(name, avg))) +
  geom_point(size=3) + # ドットを大きくする 
  theme_bw() + theme(panel.grid.major.x = element_blank(), #x軸のmajor(軸目盛り部分)をなし
                     panel.grid.minor.x = element_blank(), #x軸のminor(軸目盛りがない部分)をなし
                     panel.grid.major.y = element_line(colour="grey60", linetype="dashed") #y軸のmajorを灰色、破線
                     # カテゴリカルなのでyのminorはなし
                     )

f:id:chito_ng:20190217170059p:plain

# nameを取得し、最初にlgでソートし、次にavgでソートする
nameorder <- tophit$name[order(tophit$lg, tophit$avg)] 

# nameをnameorderの順序のレベルを持つファクタに変換する 
tophit$name2 <- factor(tophit$name, levels=nameorder)

ggplot(tophit, aes(x=avg, y=name2, color = lg)) +
  geom_point(size=3) + # ドットを大きくする 
  theme_bw() + theme(panel.grid.major.x = element_blank(), #x軸のmajor(軸目盛り部分)をなし
                     panel.grid.minor.x = element_blank(), #x軸のminor(軸目盛りがない部分)をなし
                     panel.grid.major.y = element_line(colour="grey60", linetype="dashed") #y軸のmajorを灰色、破線
                     # カテゴリカルなのでyのminorはなし
  ) +
  facet_grid(lg ~ ., scales = 'free_y', space = 'free_y') #scaleでfacetの大きさを、 spaceで文字の大きさを自動設定

f:id:chito_ng:20190217173515p:plain

軸の範囲

軸の範囲を指定する方法は切り出しと拡大の2つがある。
切り出しの場合、その範囲外のデータは捨てるのに対して、拡大は表示はされないが存在する。

ちなみに、信頼区間を出している場合、切り出しで点や線は範囲内にあっても信頼区間が切り出される場合はその信頼区間は非表示になる。

library(ggpubr)

#全体
g1 = ggplot(BOD, aes(x=Time, y=demand)) +
  geom_line() +
  scale_y_continuous(limits = c(0, 20)) +
  ggtitle("all")

#切り出し
g2 = ggplot(BOD, aes(x=Time, y=demand)) + 
  geom_line() + 
  scale_y_continuous(limits = c(0, 17)) +
  ggtitle("cutting")

#拡大
g3 = ggplot(BOD, aes(x=Time, y=demand)) +
  geom_line() +
  coord_cartesian(ylim= c(0,17)) +
  ggtitle("zoom")

ggarrange(g1,g2,g3)

f:id:chito_ng:20190217181205p:plain

軸の表示形式

対数変換

g2 <- g1 + scale_x_log10() + scale_y_log10()

g1 | g2

f:id:chito_ng:20190222191642p:plain

10のx乗表示⇔数値

桁数が大きいと指数表示となる。

sample <- c("A", "B", "C")
x   <- c("x1", "x2", "x3")
y   <- c(3205025,124135135,35246406)

d <- data.frame(sample = sample, x = x, y = y)

ggplot(d, aes(x = x, y = y, fill = sample)) +
  geom_bar(stat = "identity", position = "dodge")

f:id:chito_ng:20190223154018p:plain

これを回避するには、options(scipen=...)を用いる。これを用いると指数表示になる桁数を制御できる。

1000000
# = > [1] 1e+06

options(scipen=1000)
1000000
# => 1000000
options(scipen=1000)

ggplot(d, aes(x = x, y = y, fill = sample)) +
  geom_bar(stat = "identity", position = "dodge")

f:id:chito_ng:20190223154759p:plain