【ggplotメモ16】折れ線グラフを描く(その2)

以前折れ線グラフの描き方について書いた際(【ggplotメモ6】折れ線グラフを描く)、複数の折れ線グラフを1つの図に載せる方法を書いていなかったなと思い出しました。ということで、今日は折れ線グラフを2本書いてみたいと思います。

 

前回は「airquality」というデータを使ったのですが、「airquality」には1地点(ニューヨーク)のデータしかありません。今回は横軸を日付として、複数地点の気温データをプロットしたいので、気象庁から大阪と東京の直近1ヶ月の気温データをダウンロードしてきました。ダウンロードしたcsvファイルをExcelで開いて見てみましょう。

 

 

え、何これ、めんどくさ……。すぐに使える形になってないのか……。

しょうがないのでR上でいい感じに整形していきましょう。

 

 

前処理

まずは「data」フォルダに入れておいたcsvファイルを読み込みます。ファイル名は「data」です。

# データの読み込み(東京と大阪の気温データ)
data = read.csv("data/data.csv", skip = 5, header = F)

日本語が混じっているとエラーになってしまうので、最初の5行を「skip = 5」で消しました。

また、「header = F」をつけてこの中にヘッダーはないよ、と指定します。「header = F」を入れておかないと、2021/5/4の行がヘッダーとして認識されてしまいます。

読み込まれたデータがこちら。列名は自動で「V1 V2……」とつけておいてくれます。

> head(data) 
        V1   V2 V3 V4   V5 V6 V7 
1 2021/5/4 18.0  8  1 18.5  8  1 
2 2021/5/5 18.3  8  1 17.3  8  1 
3 2021/5/6 18.5  8  1 19.2  8  1 
4 2021/5/7 17.5  8  1 17.6  8  1 
5 2021/5/8 19.5  8  1 18.7  8  1 
6 2021/5/9 23.0  8  1 20.5  8  1

 

日付と気温以外のデータは必要ないので、消しちゃいたいと思います。

# 不要な列を削除
data = data[,c(-3, -4, -6, -7)]

data[行番号,列番号]」で行と列の指定ができます。今回は行の抽出はしないので何も書かず、列番号だけ指定しましょう。「-3」とすることで「3列目を削除してね」と指示できます。「c()」で消したい列番号のベクトルを作ることで、一括で削除できます。

dataがこんな感じになりました。

> head(data) 
        V1   V2   V5 
1 2021/5/4 18.0 18.5 
2 2021/5/5 18.3 17.3 
3 2021/5/6 18.5 19.2 
4 2021/5/7 17.5 17.6 
5 2021/5/8 19.5 18.7 
6 2021/5/9 23.0 20.5

 

「V1……」のままではわかりづらいので、列名を変更しておきましょう。確か東京の方が左側でしたね。

# 列名の変更
colnames(data) = c("Date", "Tokyo", "Osaka")

colnames(データフレーム名)」で列名を変更できます。ここでも「c()」を使うことで、3つ一気に変更します。

> head(data) 
      Date Tokyo Osaka 
1 2021/5/4  18.0  18.5 
2 2021/5/5  18.3  17.3 
3 2021/5/6  18.5  19.2 
4 2021/5/7  17.5  17.6 
5 2021/5/8  19.5  18.7 
6 2021/5/9  23.0  20.5

 

今のwide形式のデータだとグラフを作りづらいので、long形式に変換したいと思います。「tidyr」という便利パッケージの「gather」関数を使ってみました。

# ロング型に変更
library(tidyr)
data = gather(data, key = "City", value = "Temp", Tokyo, Osaka)

key = 」で「Tokyo」「Osaka」を入れる列名を指定します。今回は「"City"」という名前にします。そして、「value =」で今Tokyo列・Osaka列に入っているデータを入れる列名を指定します。今回は気温(temperature)の略「"Temp"」という名前にします。

最近は「tidyr」に「pivot_longer()」という関数ができています。「gather」関数はちょっとややこしいので、「pivot_longer()」も使ってみてください。

この時点でできたものがこちら。上からTokyoのデータがばーっと入った後ろに、Osakaのデータが入っています。

> head(data) 
      Date  City Temp 
1 2021/5/4 Tokyo 18.0 
2 2021/5/5 Tokyo 18.3 
3 2021/5/6 Tokyo 18.5 
4 2021/5/7 Tokyo 17.5 
5 2021/5/8 Tokyo 19.5 
6 2021/5/9 Tokyo 23.0

> tail(data) 
        Date  City Temp 
59 2021/5/30 Osaka 21.8 
60 2021/5/31 Osaka 22.2 
61  2021/6/1 Osaka 23.2 
62  2021/6/2 Osaka 23.4 
63  2021/6/3 Osaka 22.9 
64  2021/6/4 Osaka 20.3

 

今、「Date」列には年数「2021」も入っているのですが、今回は省略しようかなと思います。

# 年数を削除
a = format(as.Date(data$Date, format = "%Y/%m/%d"),"%m/%d")
library(dplyr)
data = mutate(data, Date = a)

「年月日」の情報から「月日」だけを取り出したベクトル「a」を作ります。これを実現するために、「as.Date」を使ってデータフレーム「data」の「Date」列を日付型に変えています。「as.Date()」の中の「format = 」は指定した列にどのような形の日付情報が入っているかを教えてあげています。YがYear、mがmonth、dがdayです。

一方、「as.Date()」を囲っている「format()」関数は、日時データを表す文字列を作成するための関数です。「as.Date()」の後ろに「"%m/%d"」と書くことで「月日」だけを取り出してほしいことを伝えています。

そして、これまた便利パッケージ「dplyr」の「mutate」関数を使って、データフレーム「data」の「Date」列の情報を先に作っておいた「a」に置き換えます。

出来上がった「data」はこんな感じ。やっと作図ができそうです。

> head(data) 
   Date  City Temp 
1 05/04 Tokyo 18.0 
2 05/05 Tokyo 18.3 
3 05/06 Tokyo 18.5 
4 05/07 Tokyo 17.5 
5 05/08 Tokyo 19.5 
6 05/09 Tokyo 23.0

もしかしたらもう少し効率的に前処理を行うこともできるのかもしれませんが……。今回私が思いついた方法は以上の通りでした。もしもっといい方法があったらぜひ教えてください。

 

 

作図

ここまで来たら、作図自体は簡単です。

# ggplot2の読み込み
library(ggplot2)

# グラフの基本設定
theme_set(theme_classic(base_size = 15, base_family = "Hiragino Kaku Gothic Pro W3"))

# 描画
l4 = ggplot(data, aes(x = Date, y = Temp, color = City, group = City)) +
 geom_line(size = 2) +
 geom_point(aes(shape = City, size = 2)) +
 guides(size = FALSE) +
 xlab("日") +
 ylab("気温(℃)") +
 coord_cartesian(ylim = c(15, 25)) +
 theme(
  axis.text.x = element_text(angle = 90, hjust = 1),
  axis.text.y = element_text(size = 20),
  axis.title = element_text(size = 20),
  legend.text = element_text(size = 20),
  legend.title = element_text(size = 20)
 )

ggplot2」を読み込み、お好きなスタイルを設定したら、「geom_line() 」を使って折れ線グラフを描きましょう。

複数の折れ線を1つのグラフに載せるときのポイントは「ggplot()」の中で「color =」と「group =」を指定することです。ここで「City」と書いておくことで、Tokyoの折れ線とOsakaの折れ線が色分けされて表示されます。

また、「geom_point(aes(shape = City))」と書くことで、データポイントの形もTokyoとOsakaで変えておきます。

線の太さ・点の大きさを指定したら凡例が出てきてしまったので、「guides(size = FALSE) 」で消しました。

最後の「theme()」の中では細々と見た目を整えています。「axis.text.x」では日付の表示の角度を変えていて、他は日付以外のフォントサイズをひとつずつ変えています。

以上のコードを書いて出来上がった図がこちら。

 

こんな感じで折れ線グラフを2本書くことができました。

 

保存するためのコードの書き方は以下の通りです。横長サイズで保存しています。

savePlot = function(data, name, dpi, width, height){
 ggsave(plot = data, file = name, dpi = dpi, width = width / dpi, height = height / dpi)
}
savePlot(l4, "figure/plot5c.png", 300, 3000, 1500)

 

以上、複数の折れ線グラフを1つの図に載せる方法でした。