このリポジトリの目標は、私が学んだいくつかのきちんとしたggplot2トリックを追跡することです。これは、GGPLOT2の基本に精通していることを前提としており、自分の素晴らしいプロットを構築できます。そうでない場合は、本をあなたのレジャーで熟読してください。
私は輝かしく整形のプロットや巧妙に微調整されたテーマやカラーパレットに信じられないほど適応していないので、あなたは私を許さなければなりません。 mpg
データセットはプロットに非常に汎用性が高いため、読んでいると多くのことが表示されます。拡張パッケージは素晴らしいです、そして私は自分自身を手にしましたが、私はここでバニラggplot2のトリックに自分自身を制限しようとします。
今のところ、これは主にReadmeのみのトリックのバッグになりますが、後で他のファイルの別々のグループにそれらを配置することを決めるかもしれません。
ライブラリをロードし、プロットテーマを設定することにより。ここでの最初のトリックは、 theme_set()
使用して、ドキュメント全体ですべてのプロットのテーマを設定することです。すべてのプロットに非常に冗長なテーマを設定することに気付いた場合、ここにすべての共通の設定を設定する場所があります。その後、テーマ要素の小説を二度と書くことは決してありません1 !
library( ggplot2 )
library( scales )
theme_set(
# Pick a starting theme
theme_gray() +
# Add your favourite elements
theme(
axis.line = element_line(),
panel.background = element_rect( fill = " white " ),
panel.grid.major = element_line( " grey95 " , linewidth = 0.25 ),
legend.key = element_rect( fill = NA )
)
)
?aes
ドキュメントはこれを伝えませんが、ggplot2のmapping
引数をスプライスできます。それはどういう意味ですか?まあ、それはあなたが外出先でmapping
引数を作成できることを意味します!!!
。たまに美学をリサイクルする必要がある場合、これは特に気の利いています。
my_mapping <- aes( x = foo , y = bar )
aes( colour = qux , !!! my_mapping )
# > Aesthetic mapping:
# > * `x` -> `foo`
# > * `y` -> `bar`
# > * `colour` -> `qux`
私の個人的なお気に入りの使用は、 fill
色をcolour
色と一致させることですが、わずかに軽い2です。この場合、これにはafter_scale()
評価システムを使用します。この場合は、このセクションに続くセクションに詳細が表示されます。このドキュメント全体でこのトリックを数回繰り返します。
my_fill <- aes( fill = after_scale(alpha( colour , 0.3 )))
ggplot( mpg , aes( displ , hwy )) +
geom_point(aes( colour = factor ( cyl ), !!! my_fill ), shape = 21 )
少数の変数のヒートマップを作成するように求められる状況にいることがあります。通常、シーケンシャルスケールは明るいものから暗いもの、またはその逆に実行されるため、単一色のテキストを読みにくくします。暗い背景に白でテキストを自動的に書き、明るい背景に黒を記述する方法を考案できます。以下の関数は、色の軽さの値を考慮し、その軽さに応じて黒または白のいずれかを返します。
contrast <- function ( colour ) {
out <- rep( " black " , length( colour ))
light <- farver :: get_channel( colour , " l " , space = " hcl " )
out [ light < 50 ] <- " white "
out
}
これで、レイヤーのmapping
引数にオンデマンドで審美的にスプライスされるようにすることができます。
autocontrast <- aes( colour = after_scale(contrast( fill )))
最後に、自動コントラストの仕掛けをテストできます。それがスケールに適応することに気付くかもしれませんので、このためにたくさんの条件付き書式を行う必要はありません。
cors <- cor( mtcars )
# Melt matrix
df <- data.frame (
col = colnames( cors )[as.vector(col( cors ))],
row = rownames( cors )[as.vector(row( cors ))],
value = as.vector( cors )
)
# Basic plot
p <- ggplot( df , aes( row , col , fill = value )) +
geom_raster() +
geom_text(aes( label = round( value , 2 ), !!! autocontrast )) +
coord_equal()
p + scale_fill_viridis_c( direction = 1 )
p + scale_fill_viridis_c( direction = - 1 )
ハーフジョームバージョンのものを提供するいくつかの拡張機能があります。私が知っているものの、GghalvesとSee Packageはいくつかのハーフジョームを提供しています。
遅延した評価システムを乱用して独自のものを作る方法は次のとおりです。これは、この機能だけに余分な依存を引き受けたくない場合に役立つ可能性があります。
簡単なケースはBoxPlotです。 xmin
またはxmax
after_scale(x)
に設定して、それぞれBoxPlotの右側と左部を保持できます。これはposition = "dodge"
でまだ正常に動作します。
# A basic plot to reuse for examples
p <- ggplot( mpg , aes( class , displ , colour = class , !!! my_fill )) +
guides( colour = " none " , fill = " none " ) +
labs( y = " Engine Displacement [L] " , x = " Type of car " )
p + geom_boxplot(aes( xmin = after_scale( x )))
BoxPlotsで機能するのと同じことは、エラーバーでも機能します。
p + geom_errorbar(
stat = " summary " ,
fun.data = mean_se ,
aes( xmin = after_scale( x ))
)
私たちは再びバイオリンのプロットについても同じことをすることができますが、レイヤーはxmin
美学について知らないことに不満を言います。それはその美学を使用しますが、データがセットアップされた後にのみ、ユーザーにアクセス可能な美学であることを意図したものではありません。 xmin
デフォルトをNULL
に更新することにより、警告を黙らせることができます。つまり、文句を言うことはありませんが、欠席した場合は使用しません。
update_geom_defaults( " violin " , list ( xmin = NULL ))
p + geom_violin(aes( xmin = after_scale( x )))
今回は読者にとって演習として残されていませんが、2つの半分を組み合わせて、お互いから少し相殺したい場合、どのように機能するかを示したかっただけです。エラーバーを悪用して、BoxPlotsのステープルとして機能します。
# A small nudge offset
offset <- 0.025
# We can pre-specify the mappings if we plan on recycling some
right_nudge <- aes(
xmin = after_scale( x ),
x = stage( class , after_stat = x + offset )
)
left_nudge <- aes(
xmax = after_scale( x ),
x = stage( class , after_stat = x - offset )
)
# Combining
p +
geom_violin( right_nudge ) +
geom_boxplot( left_nudge ) +
geom_errorbar( left_nudge , stat = " boxplot " , width = 0.3 )
あなたが私よりも良い色の直観を持っているとし、あなたの分岐したカラーパレットのニーズには3つの色が十分ではないとしましょう。苦痛は、制限が完全に中心になっていない場合、中間点を正しくするのが難しいことです。 scales::rescale_mid()
でリーグでrescaler
引数を入力します。
my_palette <- c( " dodgerblue " , " deepskyblue " , " white " , " hotpink " , " deeppink " )
p <- ggplot( mpg , aes( displ , hwy , colour = cty - mean( cty ))) +
geom_point() +
labs(
x = " Engine displacement [L] " ,
y = " Highway miles per gallon " ,
colour = " Centered n value "
)
p +
scale_colour_gradientn(
colours = my_palette ,
rescaler = ~ rescale_mid( .x , mid = 0 )
)
別の方法は、xの制限を単純に中心にすることです。スケールの制限に関数を提供することで、それを行うことができます。
p +
scale_colour_gradientn(
colours = my_palette ,
limits = ~ c( - 1 , 1 ) * max(abs( .x ))
)
geom_text()
でポイントにラベルを付けることができますが、潜在的な問題は、テキストとポイントが重複することです。
set.seed( 0 )
df <- USArrests [sample(nrow( USArrests ), 5 ), ]
df $ state <- rownames( df )
q <- ggplot( df , aes( Murder , Rape , label = state )) +
geom_point()
q + geom_text()
この問題にはいくつかの典型的な解決策があり、それらにはすべて欠点があります。
nudge_x
およびnudge_y
パラメーターを設定できます。ここでの問題は、これらがデータユニットで定義されているため、間隔は予測不可能であり、これらを元の場所に依存させる方法はありません。hjust
とvjust
美学を設定できます。元の場所に依存することができますが、これらには自然なオフセットはありません。アクション中のオプション2と3は次のとおりです。
q + geom_text( nudge_x = 1 , nudge_y = 1 )
q + geom_text(aes(
hjust = Murder > mean( Murder ),
vjust = Rape > mean( Rape )
))
「より広いオフセットを取得するために正当化を掛けることができます」と思うかもしれません。ただし、正当化はテキストのサイズに依存するため、不平等なオフセットが得られる可能性があります。下のプロットでは、「ノースダコタ」はY指向ではあまりにもむしろ、X方向に「ロードアイランド」がオフセットされていることに注意してください。
q + geom_text(aes(
label = gsub( " North Dakota " , " North n Dakota " , state ),
hjust = (( Murder > mean( Murder )) - 0.5 ) * 1.5 + 0.5 ,
vjust = (( Rape > mean( Rape )) - 0.5 ) * 3 + 0.5
))
geom_label()
の良いことは、ラベルボックスをオフにしてテキストを保持できることです。そうすれば、 label.padding
のような他の便利なものを使用して、テキストからラベルまで絶対的な(データ非依存)オフセットを提供することができます。
q + geom_label(
aes(
label = gsub( " " , " n " , state ),
hjust = Murder > mean( Murder ),
vjust = Rape > mean( Rape )
),
label.padding = unit( 5 , " pt " ),
label.size = NA , fill = NA
)
これは以前は、パネルにファセットタグを置くことに関するヒントでしたが、これは複雑でした。 GGPLOT2 3.5.0を使用すると、無限の位置を設定し、 hjust
またはvjust
パラメーターを微調整することをいじる必要はなくなります。これで、 x = I(0.95), y = I(0.95)
を使用して、右上隅にテキストを配置できます。詳細を開いて、古いヒントを表示します。
ファセットされたプロットにテキスト注釈を置くことは痛みです。なぜなら、制限はパネルごとに異なる可能性があるため、正しい位置を見つけることは非常に困難です。この痛みを軽減することを探る拡張機能はタガーの拡張ですが、バニラggplot2で同様のことをすることができます。
幸いなことに、GGPLOT2の位置軸には、それぞれスケールの最小-Inf
と最大制限3と解釈できるようにInf
メカニックがあります。 x = Inf, y = Inf
選択してラベルをコーナーに置くことで、これを悪用できます。また、 Inf
の代わりに-Inf
使用して、上部の代わりに下部に配置するか、右ではなく左に配置することもできます。
hjust
/ vjust
引数をプロットの側面に一致させる必要があります。 x/y = Inf
の場合、それらはhjust/vjust = 1
である必要があり、 x/y = -Inf
の場合、 hjust/vjust = 0
である必要があります。
p + facet_wrap( ~ class , scales = " free " ) +
geom_text(
# We only need 1 row per facet, so we deduplicate the facetting variable
data = ~ subset( .x , ! duplicated( class )),
aes( x = Inf , y = Inf , label = LETTERS [seq_along( class )]),
hjust = 1 , vjust = 1 ,
colour = " black "
)
残念ながら、これはテキストをパネルの境界にまっすぐに置き、私たちの美しさを怒らせるかもしれません。 geom_label()
使用することで少しファンシーになります。これにより、 label.padding
設定することで、テキストとパネルの境界線の間の間隔をより正確に制御できます。
さらに、 label.size = NA, fill = NA
使用して、geomのテキストボックス部分を非表示にできます。イラストのために、トップの右ではなく、左上にタグを配置します。
p + facet_wrap( ~ class , scales = " free " ) +
geom_label(
data = ~ subset( .x , ! duplicated( class )),
aes( x = - Inf , y = Inf , label = LETTERS [seq_along( class )]),
hjust = 0 , vjust = 1 , label.size = NA , fill = NA ,
label.padding = unit( 5 , " pt " ),
colour = " black "
)
さまざまなデータセットと列を使用して、多数の同様のプロットを作成することを任されているとしましょう。たとえば、特定のプリセットを使用して、一連のBarplots 4を作成したい場合があります。バーがX軸に触れて、垂直グリッドラインを描かないようにしたいと思います。
同様のプロットをたくさん作成するよく知られている方法の1つは、プロット構造を関数に包むことです。そうすれば、機能に必要なすべてのプリセットをエンコードすることができます。
私はあなたが知らないかもしれません、 aes()
関数を使用してプログラムするさまざまな方法があり、 {{ }}
(Curly-Curly)を使用することは、より柔軟な方法の1つです5 。
barplot_fun <- function ( data , x ) {
ggplot( data , aes( x = {{ x }})) +
geom_bar( width = 0.618 ) +
scale_y_continuous( expand = c( 0 , 0 , 0.05 , 0 )) +
theme( panel.grid.major.x = element_blank())
}
barplot_fun( mpg , class )
このアプローチの欠点の1つは、関数引数の美学をロックインすることです。これを回避するために、さらに簡単な方法は...
単にaes()
に直接通過することです。
barplot_fun <- function ( data , ... ) {
ggplot( data , aes( ... )) +
geom_bar( width = 0.618 ) +
scale_y_continuous( expand = c( 0 , 0 , 0.1 , 0 )) +
theme( panel.grid.major.x = element_blank())
}
barplot_fun( mpg , class , colour = factor ( cyl ), !!! my_fill )
非常によく似たことをする別の方法は、プロット「スケルトン」を使用することです。スケルトンの背後にあるアイデアは、 data
引数の有無にかかわらずプロットを構築し、後で詳細を追加できるということです。次に、実際にプロットを作成したい場合は、 %+%
使用してデータセットを入力または交換することができ、 + aes(...)
関連する美学を設定できます。
barplot_skelly <- ggplot() +
geom_bar( width = 0.618 ) +
scale_y_continuous( expand = c( 0 , 0 , 0.1 , 0 )) +
theme( panel.grid.major.x = element_blank())
my_plot <- barplot_skelly % + % mpg +
aes( class , colour = factor ( cyl ), !!! my_fill )
my_plot
これらのスケルトンについてのきちんとしたことの1つは、 data
既に埋め込んでmapping
引数を入力しても、何度も何度も交換できるということです。
my_plot % + % mtcars +
aes( factor ( carb ), colour = factor ( cyl ), !!! my_fill )
ここでのアイデアは、プロット全体をスケルトン化するのではなく、頻繁に再利用された部品のセットだけをスケルトン化することです。たとえば、バープロットにラベルを付け、ラベル付けされたバープロットを構成するすべてのものをまとめたいと思うかもしれません。これの秘trickは、これらのコンポーネントを+
と一緒に追加しないことですが、単にlist()
に配置することです。その後、メインプロットコールと一緒にリストを+
labelled_bars <- list (
geom_bar( my_fill , width = 0.618 ),
geom_text(
stat = " count " ,
aes( y = after_stat( count ),
label = after_stat( count ),
fill = NULL , colour = NULL ),
vjust = - 1 , show.legend = FALSE
),
scale_y_continuous( expand = c( 0 , 0 , 0.1 , 0 )),
theme( panel.grid.major.x = element_blank())
)
ggplot( mpg , aes( class , colour = factor ( cyl ))) +
labelled_bars +
ggtitle( " The `mpg` dataset " )
ggplot( mtcars , aes( factor ( carb ), colour = factor ( cyl ))) +
labelled_bars +
ggtitle( " The `mtcars` dataset " )
#> ─ Session info ───────────────────────────────────────────────────────────────
#> setting value
#> version R version 4.3.2 (2023-10-31 ucrt)
#> os Windows 11 x64 (build 22631)
#> system x86_64, mingw32
#> ui RTerm
#> language (EN)
#> collate English_Netherlands.utf8
#> ctype English_Netherlands.utf8
#> tz Europe/Amsterdam
#> date 2024-02-27
#> pandoc 3.1.1
#>
#> ─ Packages ───────────────────────────────────────────────────────────────────
#> package * version date (UTC) lib source
#> cli 3.6.2 2023-12-11 [] CRAN (R 4.3.2)
#> colorspace 2.1-0 2023-01-23 [] CRAN (R 4.3.2)
#> digest 0.6.34 2024-01-11 [] CRAN (R 4.3.2)
#> dplyr 1.1.4 2023-11-17 [] CRAN (R 4.3.2)
#> evaluate 0.23 2023-11-01 [] CRAN (R 4.3.2)
#> fansi 1.0.6 2023-12-08 [] CRAN (R 4.3.2)
#> farver 2.1.1 2022-07-06 [] CRAN (R 4.3.2)
#> fastmap 1.1.1 2023-02-24 [] CRAN (R 4.3.2)
#> generics 0.1.3 2022-07-05 [] CRAN (R 4.3.2)
#> ggplot2 * 3.5.0.9000 2024-02-27 [] local
#> glue 1.7.0 2024-01-09 [] CRAN (R 4.3.2)
#> gtable 0.3.4 2023-08-21 [] CRAN (R 4.3.2)
#> highr 0.10 2022-12-22 [] CRAN (R 4.3.2)
#> htmltools 0.5.7 2023-11-03 [] CRAN (R 4.3.2)
#> knitr 1.45 2023-10-30 [] CRAN (R 4.3.2)
#> labeling 0.4.3 2023-08-29 [] CRAN (R 4.3.1)
#> lifecycle 1.0.4 2023-11-07 [] CRAN (R 4.3.2)
#> magrittr 2.0.3 2022-03-30 [] CRAN (R 4.3.2)
#> munsell 0.5.0 2018-06-12 [] CRAN (R 4.3.2)
#> pillar 1.9.0 2023-03-22 [] CRAN (R 4.3.2)
#> pkgconfig 2.0.3 2019-09-22 [] CRAN (R 4.3.2)
#> R6 2.5.1 2021-08-19 [] CRAN (R 4.3.2)
#> ragg 1.2.7 2023-12-11 [] CRAN (R 4.3.2)
#> rlang 1.1.3 2024-01-10 [] CRAN (R 4.3.2)
#> rmarkdown 2.25 2023-09-18 [] CRAN (R 4.3.2)
#> rstudioapi 0.15.0 2023-07-07 [] CRAN (R 4.3.2)
#> scales * 1.3.0 2023-11-28 [] CRAN (R 4.3.2)
#> sessioninfo 1.2.2 2021-12-06 [] CRAN (R 4.3.2)
#> systemfonts 1.0.5 2023-10-09 [] CRAN (R 4.3.2)
#> textshaping 0.3.7 2023-10-09 [] CRAN (R 4.3.2)
#> tibble 3.2.1 2023-03-20 [] CRAN (R 4.3.2)
#> tidyselect 1.2.0 2022-10-10 [] CRAN (R 4.3.2)
#> utf8 1.2.4 2023-10-22 [] CRAN (R 4.3.2)
#> vctrs 0.6.5 2023-12-01 [] CRAN (R 4.3.2)
#> viridisLite 0.4.2 2023-05-02 [] CRAN (R 4.3.2)
#> withr 3.0.0 2024-01-16 [] CRAN (R 4.3.2)
#> xfun 0.41 2023-11-01 [] CRAN (R 4.3.2)
#> yaml 2.3.8 2023-12-11 [] CRAN (R 4.3.2)
#>
#>
#> ──────────────────────────────────────────────────────────────────────────────
さて、あなたはあなたのドキュメントの開始時に一度それをする必要があります。しかし、それから二度と!次のドキュメントを除きます。 plot_defaults.R
Scriptとsource()
をドキュメントから書き込むだけです。すべてのプロジェクトのスクリプトをコピーします。それから、本当に、二度と決して:心:。 ↩
これは嘘です。現実には、塗りつぶしを明るくする代わりにaes(colour = after_scale(colorspace::darken(fill, 0.3)))
を使用します。ただし、このReadmeに{Colorspace}に依存したくありませんでした。 ↩
たとえばoob = scales::oob_censor_any
設定してプロットを自己避難しない限り。 ↩
あなたの魂の魂の中で、あなたは本当にたくさんのバープロットを作りたいですか? ↩
var
の方法は、 .data
代名詞を使用することです。これは、事前にその列をロックする場合は.data[[var]]
.data$var
になります。 ↩
このビットはもともと「部分的なスケルトン」と呼ばれていましたが、胸郭はスケルトンの一部であるため、このタイトルはより刺激的に聞こえました。 ↩