Pytanie w sprawie ggplot2, r – zmień domyślną paletę kolorów w ggplot

20

Napisałem funkcję, która zwraca wektor nazw kolorów:

<code>custom.colors <- function(n) {
  palette <- c("dodgerblue1", "skyblue4", "chocolate1", "seagreen4",
               "bisque3", "red4", "purple4", "mediumpurple3",
               "maroon", "dodgerblue4", "skyblue2", "darkcyan",
               "darkslategray3", "lightgreen", "bisque",
               "palevioletred1", "black", "gray79", "lightsalmon4",
               "darkgoldenrod1")
  if (n > length(palette))
    warning('palette has duplicated colours')
  rep(palette, length.out=n)
}
</code>

Chciałbym, aby ggplot używał powyższej funkcji do generowania domyślnie palety. Może tylko dla dyskretnych skal. Za pomocąscale_manual() za każdym razem jest to zbyt trudne. Czy to możliwe?

ten post powinien być przydatny. baptiste
Dzięki. Zatrzymam to na później, ale teraz utknąłem z wersją 0.8.9. Ernest A

Twoja odpowiedź

3   odpowiedź
7

@baptiste wskazał mi post na forum, który wspomina o funkcjiset_default_scale które można wykorzystać do ustawienia domyślnej palety. Poniższe rozwiązanie działa jednak tylko ze starymi wersjami ggplot2.

Najpierw potrzebujemy funkcji, która tworzy nazwy kolorów lub kody. Zadzwoniłem do mniemagazine.colours:

<code>magazine.colours <- function(n, set=NULL) {
  set <- match.arg(set, c('1', '2'))
  palette <- c("red4", "darkslategray3", "dodgerblue1", "darkcyan",
               "gray79", "black", "skyblue2", "dodgerblue4",
               "purple4", "maroon", "chocolate1", "bisque3", "bisque",
               "seagreen4", "lightgreen", "skyblue4", "mediumpurple3",
               "palevioletred1", "lightsalmon4", "darkgoldenrod1")
  if (set == 2)
    palette <- rev(palette)
  if (n > length(palette))
    warning('generated palette has duplicated colours')
  rep(palette, length.out=n)
}
</code>

(Akceptuje opcjonalneset argument tylko po to, aby pokazać, że nie jesteś ograniczony do jednej palety.) Ok, teraz tworzymy „skalę”, którą nazwałemmagazine. Jest oparty na skali piwowara ggplot, a kod jest dość brzydki:

<code>ScaleMagazine <- proto(ScaleColour, expr={
  objname <- 'magazine'
  new <- function(., name=NULL, set=NULL, na.colour='yellowgreen',
                  limits=NULL, breaks = NULL, labels=NULL,
                  formatter = identity, variable, legend = TRUE) {
    b_and_l <- check_breaks_and_labels(breaks, labels)
    .$proto(name=name, set=set, .input=variable, .output=variable,
            .labels = b_and_l$labels, breaks = b_and_l$breaks,
            limits= limits, formatter = formatter, legend = legend,
            na.colour = na.colour)
  }
  output_set <- function(.) {
    missing <- is.na(.$input_set())
    n <- sum(!missing)
    palette <- magazine.colours(n, .$set)
    missing_colour(palette, missing, .$na.colour)
  }
  max_levels <- function(.) Inf
})
scale_colour_magazine <- ScaleMagazine$build_accessor(list(variable = '"colour"'))
scale_fill_magazine <- ScaleMagazine$build_accessor(list(variable = '"fill"'))
</code>

Ważne jest tutaj zdefiniowanieoutput_set która jest funkcją wywoływaną przez ggplot w celu uzyskania nazw / kodów kolorów. Ponadto, jeśli potrzebujesz dodatkowych argumentów, muszą one być zawarte wnew a później można uzyskać dostęp jako.$argument_name. W powyższym przykładzieoutput_set po prostu dzwonimagazine.colours.

Teraz sprawdź, czy nowa skala rzeczywiście działa:

<code>qplot(mpg, wt, data=mtcars, shape=21,
      colour=factor(carb), fill=factor(carb)) +
  scale_colour_magazine(set='1') +
  scale_fill_magazine(set='1')
</code>

Aby uczynić go domyślnym, po prostu użyjset_default_scale.

<code>set_default_scale("colour", "discrete", "magazine") 
set_default_scale("fill", "discrete", "magazine") 
</code>

I to będzie to.

<code>> qplot(mpg, wt, data=mtcars, colour=factor(carb), fill=factor(carb))
</code>

18

Aby ponownie zdefiniować domyślną skalę kolorów, możesz również przedefiniowaćggplot funkcjonować:

<code>ggplot <- function(...) ggplot2::ggplot(...) + scale_color_brewer(palette="Spectral")
</code>

To samo dotyczy skali wypełnienia.

prawdopodobnie spowoduje to problemy podczas mapowania zmiennej ciągłej na kolor baptiste
Proste i piękne. Peque
4

Po prostu przypisz zmienną o nazwie żądanej skali:

<code>scale_colour_discrete <- function(...)
  scale_colour_manual(..., values = c('dodgerblue1', *))
</code>

Działa to, ponieważ ggplot w miarę możliwości przyjmuje domyślne skale ze środowiska globalnego, podobnie jak:

<code>get('scale_colour_discrete', envir = globalenv())
</code>
Nie mogłem tego zrobić. Czy możesz podać przykład pracy? Sebastian Sauer
W interaktywnej sesji R, w zależności od tego, czy chcesz użyć skali dla wartości dyskretnych, czy ciągłych, oraz w zależności od tego, czy chcesz, aby była to kolor czy wypełnienie, musisz zdefiniować zmienną o nazwiescale_{colour,fill}_{discrete,continuous}, np.scale_colour_discrete <- scale_colour_viridis_d; ggplot(iris, aes(Sepal.Length, Sepal.Width, colour = Species)) + geom_point() flying sheep

Powiązane pytania