Das Ziel dieses Repositorys ist es, einige ordentliche GGPlot2 -Tricks im Auge zu behalten, die ich gelernt habe. Dies setzt voraus, dass Sie sich mit den Grundlagen von ggPlot2 vertraut gemacht haben und einige eigene Handlungen erstellen können. Wenn nicht, lesen Sie bitte das Buch in Ihrem Mieter.
Ich habe mich nicht unglaublich an herrlich ordnungsgemäße Handlungen und fachmännisch feindliche Themen und Farbpaletten anpasset, also müssten Sie mir vergeben. Der mpg
-Datensatz ist sehr vielseitig für das Planen, sodass Sie beim Lesen viel davon sehen werden. Erweiterungspakete sind großartig, und ich habe mich selbst beschäftigt, aber ich werde versuchen, mich auf Vanille -GGPLOT2 -Tricks hier zu beschränken.
Im Moment wird dies hauptsächlich eine Tricktasche nur für Readme sein, aber ich kann mich später entscheiden, sie in separate Gruppen in anderen Dateien zu versetzen.
Durch das Laden der Bibliothek und das Festlegen eines Plotthemas. Der erste Trick hier ist die Verwendung theme_set()
um ein Thema für alle Ihre Handlungen in einem Dokument festzulegen. Wenn Sie für jede Handlung ein sehr ausführliches Thema festlegen, ist hier der Ort, an dem Sie alle gemeinsamen Einstellungen festlegen. Dann schreiben Sie nie wieder einen Roman mit Themenelementen. 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 )
)
)
In der ?aes
-Dokumentation wird Ihnen dies nicht angezeigt, aber Sie können das mapping
-Argument in ggPlot2 spleißen. Was bedeutet das? Nun, es bedeutet, dass Sie das mapping
-Argument unterwegs komponieren können !!!
. Dies ist besonders raffiniert, wenn Sie von Zeit zu Zeit die Ästhetik recyceln müssen.
my_mapping <- aes( x = foo , y = bar )
aes( colour = qux , !!! my_mapping )
# > Aesthetic mapping:
# > * `x` -> `foo`
# > * `y` -> `bar`
# > * `colour` -> `qux`
Meine persönliche Favoritin ist es, die fill
der colour
zu entsprechen, aber leicht leichter 2 . Wir werden das verzögerte Bewertungssystem dafür nach after_scale()
in diesem Fall verwenden, von dem Sie mehr im Abschnitt folgen. Ich werde diesen Trick in diesem Dokument ein paar Mal wiederholen.
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 )
Möglicherweise befinden Sie sich in einer Situation, in der Sie gebeten werden, eine kleine Anzahl von Variablen zu erstellen. Normalerweise laufen sequenzielle Skalen von hell nach dunkel oder umgekehrt, wodurch Text in einer einzelnen Farbe schwer zu lesen ist. Wir könnten eine Methode entwickeln, um den Text automatisch in Weiß auf einen dunklen Hintergrund und schwarz auf hellem Hintergrund zu schreiben. Die folgende Funktion berücksichtigt einen Helligkeitswert für eine Farbe und gibt je nach Leichtigkeit entweder Schwarz oder Weiß zurück.
contrast <- function ( colour ) {
out <- rep( " black " , length( colour ))
light <- farver :: get_channel( colour , " l " , space = " hcl " )
out [ light < 50 ] <- " white "
out
}
Jetzt können wir eine Ästhetik in das mapping
einer Schicht auf Bedarf einfließen lassen.
autocontrast <- aes( colour = after_scale(contrast( fill )))
Zuletzt können wir unseren automatischen Kontrastvorsprung testen. Möglicherweise stellen Sie fest, dass es sich an die Skala anpasst, sodass Sie dafür nicht eine Reihe bedingter Formatierung durchführen müssen.
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 )
Es gibt einige Erweiterungen, die Halbgeom-Versionen von Dingen anbieten. Von denen, die ich kenne, bieten Gghalves und das See Paket ein paar halbe Geommer.
Hier erfahren Sie, wie Sie das verspätete Bewertungssystem missbrauchen, um Ihre eigenen zu machen. Dies kann nützlich sein, wenn Sie nicht bereit sind, eine zusätzliche Abhängigkeit für genau diese Funktion anzunehmen.
Der einfache Gehäuse ist der Boxplot. Sie können xmin
oder xmax
entweder auf after_scale(x)
einstellen, um die rechten bzw. linken Teile eines Boxplotes zu halten. Dies funktioniert immer noch gut mit 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 )))
Das Gleiche, was für Boxplots funktioniert, funktioniert auch für Fehlerbars.
p + geom_errorbar(
stat = " summary " ,
fun.data = mean_se ,
aes( xmin = after_scale( x ))
)
Wir können noch einmal dasselbe für Geigenplots tun, aber die Schicht beschwert sich darüber, dass sie nicht über die xmin
-Ästhetik informiert werden. Es verwendet diese Ästhetik, aber erst nach dem Einrichten der Daten, sodass es nicht als Benutzer zugänglich ist. Wir können die Warnung zum Schweigen bringen, indem wir den xmin
-Standard auf NULL
aktualisieren, was bedeutet, dass sie sich nicht beschweren, aber auch nicht verwendet, wenn es abwesend ist.
update_geom_defaults( " violin " , list ( xmin = NULL ))
p + geom_violin(aes( xmin = after_scale( x )))
Diesmal nicht als Übung für den Leser verlassen, aber ich wollte nur zeigen, wie es funktionieren würde, wenn Sie zwei Hälften kombinieren und möchten, dass sie ein wenig voneinander voneinander versetzt werden. Wir werden die Fehlerbars missbrauchen, um als Heftklammern für die Boxplots zu dienen.
# 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 )
Nehmen wir an, Sie haben eine bessere Farbintuition als ich, und drei Farben sind nicht genug für Ihre divergierenden Farbpalette. Ein Schmerz ist, dass es schwierig ist, den Mittelpunkt richtig zu machen, wenn Ihre Grenzen nicht perfekt darum geht. Geben Sie mit scales::rescale_mid()
das Argument rescaler
in der Liga ein.
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 )
)
Eine Alternative besteht darin, einfach die Grenzen auf x zu zentrieren. Wir können dies tun, indem wir den Grenzen der Skala eine Funktion bieten.
p +
scale_colour_gradientn(
colours = my_palette ,
limits = ~ c( - 1 , 1 ) * max(abs( .x ))
)
Sie können Punkte mit geom_text()
kennzeichnen, aber ein potenzielles Problem ist, dass sich der Text und die Punkte überlappen.
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()
Es gibt mehrere typische Lösungen für dieses Problem, und alle haben Nachteile:
nudge_x
und nudge_y
festlegen. Das Problem hier ist, dass diese in Dateneinheiten definiert sind, sodass der Abstand unvorhersehbar ist und es keine Möglichkeit gibt, diese von den ursprünglichen Standorten abhängen.hjust
und vjust
-Ästhetik festlegen. Sie können sich von den ursprünglichen Standorten verlassen, diese haben jedoch keine natürlichen Aussagen.Hier sind die Optionen 2 und 3 in Aktion:
q + geom_text( nudge_x = 1 , nudge_y = 1 )
q + geom_text(aes(
hjust = Murder > mean( Murder ),
vjust = Rape > mean( Rape )
))
Sie denken vielleicht: "Ich kann nur die Rechtfertigungen multiplizieren, um einen breiteren Offset zu erhalten", und Sie hätten Recht. Da die Rechtfertigung jedoch von der Textgröße abhängt, erhalten Sie möglicherweise ungleiche Offsets. Beachten Sie in der darunter liegenden Handlung, dass 'North Dakota' in der y-Region und 'Rhode Island' in der X-Region zu markieren ist.
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
))
Das schöne Ding von geom_label()
ist, dass Sie das Etikettenfeld ausschalten und den Text behalten können. Auf diese Weise können Sie weiterhin andere nützliche Dinge verwenden, z 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
)
Früher war dies ein Tipp zum Einfügen von Facetten -Tags in Panels, die früher kompliziert waren. Mit GGPLOT2 3.5.0 müssen Sie nicht mehr mit der Festlegung von unendlichen Positionen und den hjust
oder vjust
-Parametern fummeln. Sie können jetzt nur x = I(0.95), y = I(0.95)
verwenden, um Text in die obere rechte Ecke zu platzieren. Öffnen Sie die Details, um den alten Tipp zu sehen.
Das Einlegen von Textanmerkungen auf facettierende Handlungen ist ein Schmerz, da die Grenzen pro Panelbasis variieren können. Daher ist es sehr schwierig, die richtige Position zu finden. Eine Erweiterung, die untersucht, die diesen Schmerz lindert, ist die Tagger -Erweiterung, aber wir können in Vanille -GGPLOT2 etwas Ähnliches tun.
Glücklicherweise gibt es einen Mechaniker in den Positionsachsen von GGPlot2, -Inf
als minimaler bzw. maximaler Grenze der Skala interpretiert Inf
. Sie können dies ausnutzen, indem Sie x = Inf, y = Inf
wählen, um die Etiketten in eine Ecke zu stellen. Sie können auch -Inf
anstelle von Inf
verwenden, um unten anstelle von oben oder links statt rechts zu platzieren.
Wir müssen mit den hjust
/ vjust
-Argumenten an der Seite der Handlung übereinstimmen. Für x/y = Inf
müssten sie hjust/vjust = 1
sein, und für x/y = -Inf
müssen sie hjust/vjust = 0
sein.
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 "
)
Leider stellt dies den Text direkt am Grenze des Panels, was unser Schönheitsgefühl beleidigen kann. Wir können mit label.padding
geom_label()
leicht schicker werden, wodurch wir den Abstand zwischen dem Text und den Grenzen der Panel genauer steuern können.
Darüber hinaus können wir label.size = NA, fill = NA
verwenden, um den Textfeldteil des Geoms zu verbergen. Zu den Illustrationszwecken platzieren wir das Tag jetzt anstelle von oberen Rechten.
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 "
)
Nehmen wir an, wir haben die Aufgabe, ein paar ähnliche Handlungen mit unterschiedlichen Datensätzen und Spalten zu erstellen. Zum Beispiel möchten wir vielleicht eine Reihe von Barplots 4 mit bestimmten Vorsätzen erstellen: Wir möchten, dass die Balken die X-Achse berühren und nicht vertikale Gitterlinien zeichnen.
Eine bekannte Art, ein paar ähnliche Handlungen zu erstellen, besteht darin, die Handlungskonstruktion in eine Funktion zu verwandeln. Auf diese Weise können Sie alle gewünschten Voreinstellungen in Ihrer Funktion verwenden.
Ich bin nicht wissen, dass Sie nicht wissen, dass es verschiedene Methoden gibt, die mit der aes()
-Funktion () programmieren können, und {{ }}
(lockig-curly) ist eine der flexibleren Wege 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 )
Ein Nachteil dieses Ansatzes ist, dass Sie alle Ästhetik in den Funktionsargumenten einsperrten. Um dies zu umgehen, ist ein noch einfacherer Weg, einfach ...
an aes()
zu gelangen.
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 )
Eine andere Methode, eine sehr ähnliche Sache zu tun, besteht darin, die Handlung 'Skelette' zu verwenden. Die Idee hinter einem Skelett ist, dass Sie ein Diagramm mit oder ohne data
erstellen und später die Einzelheiten hinzufügen können. Wenn Sie dann tatsächlich ein Diagramm erstellen möchten, können Sie den Datensatz %+%
verwenden oder ersetzen, und + aes(...)
um die entsprechende Ästhetik festzulegen.
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
Eine nette Sache an diesen Skeletten ist, dass Sie sie, selbst wenn Sie bereits die data
und mapping
Argumenten ausgefüllt haben, sie einfach immer wieder ersetzen können.
my_plot % + % mtcars +
aes( factor ( carb ), colour = factor ( cyl ), !!! my_fill )
Die Idee hier ist, nicht die gesamte Handlung zu skelettieren, sondern nur eine häufig wiederverwendete Teilemenge. Zum Beispiel möchten wir vielleicht unsere Barplot beschriften und alle Dinge zusammenpacken, die einen beschrifteten Barplot bilden. Der Trick dafür ist, diese Komponenten nicht mit +
hinzuzufügen, sondern sie einfach in eine list()
zu setzen. Sie können dann Ihre Liste zusammen mit dem Hauptaufruf des Handels +
.
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)
#>
#>
#> ──────────────────────────────────────────────────────────────────────────────
Nun, Sie müssen es zu Beginn Ihres Dokuments einmal tun. Aber dann nie wieder! Außer in Ihrem nächsten Dokument. Schreiben Sie einfach ein Skript plot_defaults.R
und source()
das aus Ihrem Dokument. Kopieren Sie dieses Skript für jedes Projekt. Dann wirklich nie wieder: Herz:. ↩
Das ist eine Lüge. In Wirklichkeit verwende ich aes(colour = after_scale(colorspace::darken(fill, 0.3)))
anstatt die Füllung zu erleichtern. Ich wollte nicht, dass diese Readme eine Abhängigkeit von {ColorSpace} hat. ↩
Es sei denn, Sie sabotieren Ihre Diagramme, indem Sie oob = scales::oob_censor_any
in der Skala zum Beispiel in der Skala festlegen. ↩
Wollen Sie in Ihrer Seele der Seelen wirklich ein paar Barplots machen? ↩
Die Alternative besteht darin, das .data
-Pronomen zu verwenden, das .data$var
sein kann, wenn Sie diese Spalte im Voraus oder .data[[var]]
sperren möchten, wenn var
als Zeichen übergeben wird. ↩
Dieses Stück wurde ursprünglich als "partielles Skelett" bezeichnet, aber als Brustkorb ist Teil eines Skeletts, dieser Titel klang eindrucksvoller. ↩