Rで解析:ggplot2で空間データの不確実性を表現する「ggincerta」パッケージの紹介
「ggincerta」パッケージは、ggplot2に地図の不確実性を表現するレイヤーとスケールを追加するパッケージです。sfの空間データにひもづく推定値と誤差・標準偏差のような2つの数値を1つの塗り色やグリフに統合し、二変量の彩色地図、グリフを使った地図、ランダムな点で敷き詰めたピクセル地図として描き出せます。渡すデータは、ポリゴンごとに推定値と不確実性の指標を持つsfオブジェクトです。ggplot2の上に成り立つ拡張のため、ggplot2でのプロット作成に慣れていることが前提になります。地図で示す数値に誤差や標準偏差が伴う分析を行っている人に向いているのではないかと考えます。
パッケージバージョンは0.2.1。Windows 11 x64 (build 26200)のR version 4.6.1で確認しています。
パッケージのインストール
下記コマンドを実行してください。ggplot2やsfなどの依存パッケージは自動的に導入されます。
# パッケージのインストール
install.packages("ggincerta")
# パッケージの読み込み
library("ggincerta")
Loading required package: ggplot2コマンド例
詳細はコメント、パッケージのヘルプを確認してください。
ggincertaは、1つの塗り色やグリフで2つの数値を同時に見せることを目指したパッケージです。duo()とduo_pixel()は、推定値と誤差のような2つの数値をひとまとめにしたオブジェクトを作り、aes(fill = …)にそのまま渡せるようにします。geom_sf_dualmap()は塗り色と輪郭色を別々の変数に割り当てて2つの数値を重ねて見せ、geom_sf_glyph()は各領域の代表点に、色と角度で2つの数値を表す図形を置きます。geom_sf_pixel()は各領域の中にランダムな点や六角形のピクセルを敷き詰め、推定値のばらつきを点の散らばりとして表現します。scale_fill_bivariate()とmanual_bivariate_scale()は、これらのレイヤーが使う二変量の配色を組み立てるスケールです。
以降の例では、宇治茶の主産地とされる京都府南部の9市町村(宇治市・宇治田原町・和束町・南山城村・城陽市・京田辺市・木津川市・笠置町・精華町)を、位置関係を簡略化した3行3列の格子状ポリゴンに見立てます。各区画に、年間収穫量の推定値と、調査地点の少なさから生じる標準誤差を持たせた、次の擬似データを共通データとして使います。
# 乱数の種を固定して結果を再現できるようにする
set.seed(20260904)
# 宇治茶の主産地とされる京都府南部の9市町村
tea_areas <- c(
"宇治市", "宇治田原町", "和束町",
"南山城村", "城陽市", "京田辺市",
"木津川市", "笠置町", "精華町"
)
# 位置関係を簡略化した3行3列の格子状ポリゴンを作る
grid <- sf::st_make_grid(
sf::st_sfc(
sf::st_polygon(list(rbind(
c(135.75, 34.72), c(136.05, 34.72),
c(136.05, 34.96), c(135.75, 34.96),
c(135.75, 34.72)
))),
crs = 4326
),
n = c(3, 3)
)
# 市町村名、年間収穫量の推定値(トン)、調査地点数から求めた標準誤差を持つsfオブジェクトを作る
tea <- sf::st_sf(
area = tea_areas,
value = round(rnorm(9, mean = 120, sd = 25)),
sd = round(runif(9, 3, 22), 1),
geometry = grid
)[推定値と不確実性のひとまとめ化]:duoコマンド
2つの数値ベクトルをまとめて1つのオブジェクトにし、二変量のマッピングであることが分かるクラスを付けます。geom_sfのfillにそのまま渡すと、以降のscale_fill_bivariate()やmanual_bivariate_scale()が値の組み合わせとして扱ってくれます。
| オプション | 意味 | 初期値 |
|---|---|---|
| v1 | 1つ目の入力変数 | なし |
| v2 | 2つ目の入力変数 | なし |
# 推定値と標準誤差をduo()でひとまとめにする
combined <- duo(tea$value, tea$sd)
# 返り値のクラスを確認する
class(combined)
[1] "bivariate" "list"
# どの変数を束ねたかを確認する
attr(combined, "vars")
[[1]]
tea$value
[[2]]
tea$sd
# duo()の結果をfillにそのまま渡して二変量マップを描く
ggplot(tea) +
geom_sf(aes(fill = duo(value, sd)))duo()の結果をfillにそのまま渡して二変量マップを描く

[二変量カラースケールの調整]:scale_fill_bivariateコマンド
duo()でまとめた2変数のマッピングに使う配色を調整します。基準となる色や配色コマンド、ビンの数を変えることで、2つの数値の組み合わせをどう色に落とし込むかを制御できます。
| オプション | 意味 | 初期値 |
|---|---|---|
| … | ggplot2::discrete_scale()に渡すその他のオプション | なし |
| name | スケールの名前。凡例のタイトルに使う。waiver()だと最初のマッピングから取り、NULLだと凡例タイトルを省く | waiver() |
| var1_name | 凡例に使うv1の名前。NULLだとマッピングから取る | NULL |
| var2_name | 凡例に使うv2の名前。NULLだとマッピングから取る | NULL |
| colours | 配色の基準点となる色のベクトル。実際のパレットの作り方はbivar_palette()とbivar_fade_palette()を参照 | c(“#EDF8B1”, “#2C7FB8”) |
| palette_fun | coloursとn_breaksを受け取り、全ビンの組み合わせに対応する色のベクトルを返すコマンド。NULLだとbivar_palette()を使う | NULL |
| palette_params | palette_funに渡す追加のオプションのリスト | list() |
| n_breaks | 各変数に望むビンの数。整数か長さ2のベクトルで指定する。nice.breaks = TRUEだと目安として扱われ、実際のビン数は変わることがある | c(4, 4) |
| nice.breaks | 自動生成するビンの境界に、きりのよい読みやすい値を使うかどうか | TRUE |
| quantile | 変数を分位点に基づくビンで区切るかどうか。分位点が重複する場合は等幅ビンになる | FALSE |
| breaks | 2変数それぞれのビン境界を指定する長さ2のリスト。waiver()だとn_breaks、nice.breaks、quantileから自動計算する | list(waiver(), waiver()) |
| labels | ビン境界のラベルに使う文字列ベクトルかラベル付けコマンドの長さ2のリスト。waiver()だとbreaksから既定のラベルを作る | list(waiver(), waiver()) |
| limits | 2変数それぞれの範囲を指定する長さ2のリスト。連続変数では含める数値範囲、離散変数では含める水準を指定する | list(NULL, NULL) |
| transform | ビン分けの前に連続変数へ適用する変換の長さ1または2のリスト | list(“identity”, “identity”) |
| na.value | na.translate = TRUEのとき、欠損値をどの審美的属性値として表示するか | NA |
| aesthetics | このスケールが対応する審美的属性の名前 | “fill” |
| guide | 凡例を作成するコマンドかその名前 | guide_bivariate() |
# 既定の配色で二変量マップを描く
ggplot(tea) +
geom_sf(aes(fill = duo(value, sd)))
# bivar_fade_paletteに差し替えて別の配色にする
ggplot(tea) +
geom_sf(aes(fill = duo(value, sd))) +
scale_fill_bivariate(
palette_fun = bivar_fade_palette,
colours = c("#F6E8C3", "orange", "red")
)
# 収穫量と標準誤差でビンの数を変える
ggplot(tea) +
geom_sf(aes(fill = duo(value, sd))) +
scale_fill_bivariate(n_breaks = c(3, 4))
# 2変数とも等間隔の4ビンに区切る
ggplot(tea) +
geom_sf(aes(fill = duo(value, sd))) +
scale_fill_bivariate(
n_breaks = 4,
nice.breaks = FALSE
)既定の配色で二変量マップを描く

bivar_fade_paletteに差し替えて別の配色にする

収穫量と標準誤差でビンの数を変える

2変数とも等間隔の4ビンに区切る

<おすすめのRに関する書籍です>
[塗り色と輪郭色で2変数を表すデュアルマップ]:geom_sf_dualmapコマンド
各領域の塗り色と輪郭色に別々の変数を割り当て、1枚の地図で2つの数値を見せます。塗り色にduo()の結果を渡せば、塗り色自体も二変量の組み合わせとして表現できます。
| オプション | 意味 | 初期値 |
|---|---|---|
| mapping | aes()で作成した審美的属性のマッピング | NULL |
| data | このレイヤーで表示するデータ | NULL |
| … | layer()に渡すその他のオプション | なし |
| shape | グリフの形状。”circle”、”square”、”triangle”、”hex”、”drop”、”chernoff”のいずれかを指定する | “circle” |
| max_angle | angleの審美的属性を再スケーリングする際の最大値 | NULL |
| size | グリフの大きさを調整する正の数値 | 1 |
| point_fun | 各領域の代表点を求めるコマンド。既定はsf::st_point_on_surface() | sf::st_point_on_surface |
| border_colour | グリフの輪郭線の色 | NA |
| na.rm | FALSEのとき欠損値を警告付きで取り除く | FALSE |
| show.legend | このレイヤーを凡例に含めるかどうか | NA |
| inherit.aes | FALSEのとき既定の審美的属性を上書きする | TRUE |
| angle_guide | angleの凡例を表示するかどうか | TRUE |
| angle_name | angleの凡例に付けるタイトル | waiver() |
| angle_order | 他の凡例に対するangleの凡例の表示順 | 2 |
| fill_scale | 周囲の塗りに使うスケール。NULLだと、塗りのマッピングがduo()由来でない場合に既定の灰色のグラデーションを使う | NULL |
# 塗りと輪郭色をそれぞれ別の変数に割り当てたデュアルマップ
ggplot(tea) +
geom_sf_dualmap(aes(fill = sd, colour = value))
Warning message:
st_point_on_surface assumes attributes are constant over geometries
Warning message:
st_point_on_surface may not give correct results for longitude/latitude data
# 塗りをduo()による二変量スケールにし、輪郭色は対数変換した標準誤差にする
ggplot(tea) +
geom_sf_dualmap(aes(fill = duo(value, sd), colour = log2(sd)))
Warning message:
st_point_on_surface assumes attributes are constant over geometries
Warning message:
st_point_on_surface may not give correct results for longitude/latitude data塗りと輪郭色をそれぞれ別の変数に割り当てたデュアルマップ

塗りをduo()による二変量スケールにし、輪郭色は対数変換した標準誤差にする

[代表点に図形を置くグリフマップ]:geom_sf_glyphコマンド
各領域の代表点に図形(グリフ)を置き、色と角度で2つの数値を表します。角度で表す変数はangleに、色で表す変数はcolourに割り当てます。
| オプション | 意味 | 初期値 |
|---|---|---|
| mapping | aes()で作成した審美的属性のマッピング | NULL |
| data | このレイヤーで表示するデータ | NULL |
| … | layer()に渡すその他のオプション | なし |
| shape | グリフの形状。”circle”、”square”、”triangle”、”hex”、”drop”、”chernoff”のいずれかを指定する | “circle” |
| max_angle | angleの審美的属性を再スケーリングする際の最大値 | NULL |
| size | グリフの大きさを調整する正の数値 | 1 |
| point_fun | 各領域の代表点を求めるコマンド。既定はsf::st_point_on_surface() | sf::st_point_on_surface |
| border_colour | グリフの輪郭線の色 | NA |
| na.rm | FALSEのとき欠損値を警告付きで取り除く | FALSE |
| show.legend | このレイヤーを凡例に含めるかどうか | NA |
| inherit.aes | FALSEのとき既定の審美的属性を上書きする | TRUE |
| angle_guide | angleの凡例を表示するかどうか | TRUE |
| angle_name | angleの凡例に付けるタイトル | waiver() |
| angle_order | 他の凡例に対するangleの凡例の表示順 | 99 |
# 六角形のグリフで収穫量の推定値を色に割り当てる
ggplot(tea) +
geom_sf_glyph(aes(colour = value), shape = "hex")
Warning message:
st_point_on_surface assumes attributes are constant over geometries
Warning message:
st_point_on_surface may not give correct results for longitude/latitude data
# 標準誤差の大きさで向きを変えた雫型グリフ
ggplot(tea) +
geom_sf_glyph(
aes(colour = value, angle = sd),
shape = "drop"
)
Warning message:
st_point_on_surface assumes attributes are constant over geometries
Warning message:
st_point_on_surface may not give correct results for longitude/latitude data
# ggChernoffパッケージが使える場合はChernoff顔グリフで表す
if (requireNamespace("ggChernoff", quietly = TRUE)) {
ggplot(tea) +
geom_sf_glyph(
aes(colour = value, smile = sd),
shape = "chernoff"
)
}
Warning message:
st_point_on_surface may not give correct results for longitude/latitude data六角形のグリフで収穫量の推定値を色に割り当てる

標準誤差の大きさで向きを変えた雫型グリフ

ggChernoffパッケージが使える場合はChernoff顔グリフで表す

[領域内にピクセルを敷き詰めるピクセルマップ]:geom_sf_pixelコマンド
各領域の中を格子状のピクセルで埋めます。塗り色にduo_pixel()の結果を渡すと、標準誤差が大きい地域ほど点のばらつきが視覚的に伝わります。幾何演算を高速にするため、事前に平面座標系へ変換しておきます。
| オプション | 意味 | 初期値 |
|---|---|---|
| mapping | aes()で作成した審美的属性のマッピング | NULL |
| data | このレイヤーで表示するデータ | NULL |
| n | x方向とy方向のグリッド数。長さ1か2の整数で指定する | 60 |
| distribution | 各領域内でピクセルの値を抽出する分布。”uniform”か”normal”を指定する | “uniform” |
| seed | 再現性のための乱数の種 | NULL |
| pixel_shape | 生成するピクセルの形状。”hex”、”square”、”rect”のいずれか。”rect”はx方向とy方向を同じ区間数で分けるため長方形になることがある | “hex” |
| flat_topped | TRUEだと上辺が平らな六角形、FALSEだと頂点が上を向く六角形にする | FALSE |
| show.legend | このレイヤーを凡例に含めるかどうか | NA |
| inherit.aes | FALSEのとき既定の審美的属性を上書きする | TRUE |
| … | layer()に渡すその他のオプション | なし |
# 幾何演算を高速にするため、平面座標系(Webメルカトル)へ変換する
tea_flat <- sf::st_transform(tea, sf::st_crs(3857))
# 推定値と標準誤差をduo_pixel()でまとめ、六角形のピクセルで敷き詰める
ggplot(tea_flat, aes(fill = duo_pixel(value, sd))) +
geom_sf_pixel(n = 25)
# ピクセルの形状と解像度を変える
ggplot(tea_flat, aes(fill = duo_pixel(value, sd))) +
geom_sf_pixel(n = 15, pixel_shape = "square")推定値と標準誤差をduo_pixel()でまとめ、六角形のピクセルで敷き詰める

ピクセルの形状と解像度を変える

[配色を手動で指定する二変量スケール]:manual_bivariate_scaleコマンド
自動生成の配色ではなく、ビンの組み合わせごとの色を自分で指定したいときに使います。valuesには、2変数のビン数の積と同じ数以上の色を、行優先で並べて渡します。
| オプション | 意味 | 初期値 |
|---|---|---|
| aesthetics | このスケールが対応する審美的属性の名前 | なし |
| … | ggplot2::discrete_scale()に渡すその他のオプション | なし |
| values | 色を表す文字列ベクトル。長さはn_breaksの積以上必要で、2変数のビンの組み合わせごとに1色を対応させる | なし |
| name | スケールの名前。凡例のタイトルに使う。waiver()だと最初のマッピングから取り、NULLだと凡例タイトルを省く | waiver() |
| breaks | 2変数それぞれのビン境界を指定する長さ2のリスト。waiver()だとn_breaks、nice.breaks、quantileから自動計算する | list(waiver(), waiver()) |
| labels | ビン境界のラベルに使う文字列ベクトルかラベル付けコマンドの長さ2のリスト。waiver()だとbreaksから既定のラベルを作る | list(waiver(), waiver()) |
| limits | 2変数それぞれの範囲を指定する長さ2のリスト。連続変数では含める数値範囲、離散変数では含める水準を指定する | list(NULL, NULL) |
| transform | ビン分けの前に連続変数へ適用する変換の長さ1または2のリスト | list(“identity”, “identity”) |
| na.value | na.translate = TRUEのとき、欠損値をどの審美的属性値として表示するか | NA |
| na.translate | 離散スケールは既定で欠損値を表示する。表示したくない場合はna.translate = FALSEにする | TRUE |
| drop | 未使用の因子水準をスケールから除くかどうか。TRUEだとデータに現れる水準のみ使う | FALSE |
| guide | 凡例を作成するコマンドかその名前 | guide_bivariate() |
| n_breaks | 各変数に望むビンの数。整数か長さ2のベクトルで指定する | c(4, 4) |
| quantile | 変数を分位点に基づくビンで区切るかどうか。分位点が重複する場合は等幅ビンになる | FALSE |
| var1_name | 凡例に使うv1の名前。NULLだとマッピングから取る | NULL |
| var2_name | 凡例に使うv2の名前。NULLだとマッピングから取る | NULL |
| super | 構築するスケールに使う親クラス | ScaleBivariate |
# 収穫量(緑の濃さ)と標準誤差(茶の濃さ)を掛け合わせた16色を手動で指定する
ggplot(tea, aes(fill = duo(value, sd))) +
geom_sf() +
manual_bivariate_scale(
aesthetics = "fill",
values = c(
"#F7F4E9", "#D9CBA3", "#B99B5B", "#8C6D1F",
"#DCEBD5", "#B7D9A8", "#8FBF7A", "#5E9C4A",
"#B8DCE0", "#8FC4CB", "#5CA3AC", "#2E7A85",
"#C9C2E0", "#A79BCB", "#8574B0", "#5F4A94"
),
n_breaks = 4
)収穫量(緑の濃さ)と標準誤差(茶の濃さ)を掛け合わせた16色を手動で指定する

<おすすめのRに関する書籍です>
この記事が誰かの役に立ちますように。