Création d'une légende personnalisée dans r


fille ensoleillée

J'espère avoir une légende qui inclut des références à toutes les couleurs, pas seulement les lignes verticales, et n'inclut pas de titre.

J'ai essayé scale_colour_manual et scale_fill_manual et ils se chevauchent tous ou n'affichent que les lignes verticales. J'apprécierais toutes suggestions.

Reprex est ci-dessous, y compris la palette de couleurs personnalisée.

var1 <- c(head(randu$x,n=12))
var2 <- as.Date(c("2010-01-01","2010-02-01","2010-03-01","2010-04-01","2010-05-01","2010-06-01","2010-07-01","2010-08-01","2010-09-01","2010-10-01","2010-11-01","2010-12-01"))
var3 <- c(tail(randu[which(randu$x + randu$y < 1),]$x,n=12))
var4 <- c(tail(randu[which(randu$x + randu$y < 1),]$y,n=12))

dat <- data.frame(var1,var2,var3,var4)
setDT(dat)
dat$var5 <- dat[,(var3+var4)]

new_dates <- as.Date(c("2010-09-01","2010-05-01"))

cbp2 <- c("#000000", "#56B4E9", "#009E73", "#0072B2", "#D55E00", "#CC79A7")

ggplot()+
  geom_bar(data=dat,colour=cbp2[1],fill = cbp2[1],aes(x=var2,y=var5,colour="var4"),stat="identity")+
  geom_bar(data=dat,colour=cbp2[2],fill = cbp2[2],aes(x=var2,y=var3,colour="var3"),stat="identity")+
  geom_line(data=dat,colour=cbp2[1],aes(x=var2,y=var1))+
  geom_vline(data=data.frame(xintercept = new_dates),
             aes(xintercept = new_dates,linetype = "Changes", colour="red"),
             linetype="dashed",key_glyph = "path")+
  scale_color_manual(name = "",
                     values = c("red",cbp2[2],cbp2[1]), 
                     breaks = c("red",cbp2[2],cbp2[1]),
                     labels = c("Changes","Var3","Var4"))+
  scale_fill_manual(name = "",
                    values = c(cbp2[2],cbp2[1]), 
                    breaks = c(cbp2[2],cbp2[1]),
                    labels = c("var3","var4"))+
  ylab("")+
  xlab("")+
  scale_x_date(expand=c(0,0),date_breaks = "3 month", date_labels =  "%b %y") + 
  scale_y_continuous(labels = function(var5) paste0(var5*100, "%"), 
                     limits=c(0,1),
                     breaks=c(0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1)) +
  theme(panel.background = element_blank(),
        axis.line = element_line(colour = "#000000"),
        axis.text.x = element_text(angle=60, hjust=1),  
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        axis.title.x= (element_text(margin = unit(c(3, 0, 0, 0), "mm"))),
        legend.position = "top")

entrez la description de l'image ici

chemdork123

Il y a beaucoup de choses à déballer ici avec celui-ci, mais j'ai fait de mon mieux.

Tout d'abord, réfléchissez à ce que vous essayez de tracer ici. Normalement, ce n'est pas un problème d'appeler les choses var1, var2, var3,...; cependant, dans ce contexte, c'est vraiment assez déroutant. Par conséquent, pour cette solution, je publierai à nouveau l'intégralité de votre code retravaillé au lieu de simplement la partie de traçage pour des raisons que j'espère décrire dans cette réponse.

Les données et la question

Cela étant dit, voici ma compréhension de la nature de l'ensemble de données et de votre désir pour le tracé final :

  • var2dans l'ensemble de données contient Datedes informations sur la classe, et c'est l' xaxe commun pour l'ensemble du tracé.

  • var1contient des valeurs qui doivent être utilisées pour les yvaleurs de la geom_linecouche de tracé

  • var3et var4contiennent des valeurs qui doivent être utilisées pour la création du barplot empilé qui devrait constituer l'arrière-plan du tracé

  • var5est une somme de var3 + var4, et était un dispositif pour créer l'intrigue. Ici, cela ne sera pas utile, compte tenu de l'analyse des données que nous devons faire sur le jeu de données et de l'application des principes de Tidy Data.

  • xinterceptLes valeurs de la geom_vlinecouche de tracé sont fournies sous forme de deux datesnew_dates

La question du PO indique qu'il est nécessaire que la légende s'affiche correctement. Dans ce cas, nous voulons indiquer :

  • couleur de remplissage des barres au fur var3et à mesurevar4
  • la nature des lignes verticales sous forme de lignes rouges pointillées .. appelées « Changements »
  • Une étiquette pour la geom_linecouche de tracé. Supposons que l'étiquette sera var1.

J'espère que tout était correct !

Synthétiser l'ensemble de données

J'encourage le PO à consulter l'utilisation de Tidy Data Principles , ce qui rendra la synthèse de données comme celle-ci beaucoup plus simple à l'avenir. Ici, j'appliquerai ces principes à l'ensemble de données dat.

Tout d'abord, gérons les données de la couche de barres . En appliquant les principes Tidy données, nous voulons rassembler var3et var4créer sur les deux colonnes: (1) l' un pour le nom de la variable ( "var3"ou "var4"), et (2) un pour la valeur . Nous dirons ggplot2d'"empiler" les barres, ce var5n'est donc pas nécessaire ici : ggplot2fera ce calcul automatiquement. Pour rassembler les colonnes, ma préférence est toujours d'utiliser gather()from dplyret tidyr:

library(dplyr)
library(tidyr)
library(ggplot2)
library(data.table)

var1 <- c(head(randu$x,n=12))
var2 <- as.Date(c("2010-01-01","2010-02-01","2010-03-01","2010-04-01","2010-05-01","2010-06-01","2010-07-01","2010-08-01","2010-09-01","2010-10-01","2010-11-01","2010-12-01"))
var3 <- c(tail(randu[which(randu$x + randu$y < 1),]$x,n=12))
var4 <- c(tail(randu[which(randu$x + randu$y < 1),]$y,n=12))

dat <- data.frame(var1,var2,var3,var4)
setDT(dat)
# dat$var5 <- dat[,(var3+var4)]   no longer needed
new_dates <- as.Date(c("2010-09-01","2010-05-01"))
cbp2 <- c("#000000", "#56B4E9", "#009E73", "#0072B2", "#D55E00", "#CC79A7")

newdat <- dat %>% 
  gather(key='var_name', value='value', -var2) # gather all columns except for var2

names(newdat) <- c('Dates', 'var_name', 'value')
newdat$var_name <- factor(newdat$var_name, levels=c('var4', 'var3','var1'))

En plus de rassembler, vous noterez également que j'ajuste les noms des colonnes pour les rendre un peu plus faciles à suivre lorsqu'il s'agit de tracer. De plus, je définis l'ordre des niveaux pour newdat$var_name. Le but ici est que l'ordre que nous spécifions se rapporte à l'ordre utilisé pour créer l'intrigue. Je veux var3apparaître comme une barre "sous" var4, nous devons donc spécifier que var4c'est en premier.

Vous pouvez également créer un jeu de données séparé contenant var2et var1à utiliser pour tracer la geom_linecouche... mais cela fonctionne également très bien.

La parcelle

Pour l'intrigue, j'ai essayé d'organiser le code en sections distinctes. Ce que OP essayait de faire était de tracer colonne par colonne, plutôt que d'utiliser aes(fill=et aes(color=de définir et de créer des légendes. De plus, le code d'origine de l'OP contenait de nombreux exemples des éléments suivants :

geom_*(aes(color=...), color=...)

Le résultat de ceci ggplot2est que si vous définissez une valeur esthétique (comme color=) à l' extérieur de aes()tout en indiquant également cet argument à l' intérieur aes() , la valeur à l'extérieur écrasera la valeur spécifiée à l'intérieur du mappage - supprimant ainsi tout appel à placer cela dans une légende . C'était la principale cause de problème dans l'exemple du PO et pourquoi certains éléments étaient de la "bonne" couleur, mais n'apparaissaient dans aucune légende.

Spécifier des arguments dans aes()indique uniquement qu'une légende doit être créée et indique ggplot2sur quelle base appliquer la couleur, le remplissage, le type de ligne... cela ne spécifie pas réellement la couleur. La couleur doit être spécifiée à l'aide des scale_*_*()fonctions. Dans ce cas, nous avons 3 types de légendes créés. L'OP peut s'organiser comme il le souhaite, mais j'ai essayé de garder cet exemple un peu illustratif pour permettre certains changements dans le cas de l'OP, car il n'est toujours pas tout à fait clair à quoi la légende doit ressembler complètement.

Notez qui values=est utilisé pour appliquer la couleur, le type de ligne ou l'esthétique de remplissage, et se fait en alimentant cet argument en un vecteur nommé. Vous pouvez également utiliser un vecteur non nommé, auquel cas les attributs seront appliqués en fonction de l'ordre des niveaux pour ce facteur.

Notez que j'ai changé la couleur de la ligne du geom_lineen bleu... juste pour qu'il ressorte un peu. Ce serait un peu déroutant sinon, car il existe une couleur de remplissage qui est également noire.

ggplot(dat, aes(x=Dates, y=value)) +
  
  # plot layers
  geom_col(
    data=subset(newdat, var_name != 'var1'),
    aes(fill=var_name), position='stack') +
  geom_line(
    data=subset(newdat, var_name == 'var1'),
    aes(color=var_name)
  ) +
  geom_vline(data=data.frame(xintercept = new_dates),
                         aes(xintercept = new_dates, linetype = "Changes"), colour="red",
                         key_glyph = "path")+
 
  # color and legend settings 
  scale_fill_manual(
    name="Fill",
    values=c('var3'=cbp2[2], 'var4'=cbp2[1])) +
  
  scale_color_manual(
    name='Color',
    values = 'blue') +
  
  scale_linetype_manual(
    name='Linetype',
    values=2) +

  # scale adjustment and theme stuff
  scale_y_continuous(labels = function(var5) paste0(var5*100, "%"),
                     limits=c(0,1),
                     breaks=c(0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1)) +
  
  theme(panel.background = element_blank(),
                axis.line = element_line(colour = "#000000"),
                axis.text.x = element_text(angle=60, hjust=1),
                panel.grid.major = element_blank(),
                panel.grid.minor = element_blank(),
                axis.title.x= (element_text(margin = unit(c(3, 0, 0, 0), "mm"))),
                legend.position = "top")

entrez la description de l'image ici

Articles connexes


Comment créer une légende personnalisée dans matplotlib

tune2fs: Je génère actuellement ma légende avec matplotlib de cette façon: if t==25: l1,l2 = ax2.plot(x320,vTemp320,'or',x320,vAnaTemp320,'-r') elif t==50: l3,l4 = ax2.plot(x320,vTemp320,'ob',x320,vAnaTemp320,'-b') else: l5,l6 = ax2.plot(x320,vTemp

Comment créer une légende personnalisée dans matplotlib

tune2fs: Je génère actuellement ma légende avec matplotlib de cette façon: if t==25: l1,l2 = ax2.plot(x320,vTemp320,'or',x320,vAnaTemp320,'-r') elif t==50: l3,l4 = ax2.plot(x320,vTemp320,'ob',x320,vAnaTemp320,'-b') else: l5,l6 = ax2.plot(x320,vTemp

Comment ajouter une légende personnalisée dans R?

fille ensoleillée Je voudrais ajouter une légende à un graphique ggplot et je n'ai pas trouvé de réponse similaire en ligne. Ma légende doit indiquer que les lignes verticales sont les dates auxquelles les événements majeurs se sont produits et ce que les autr

Création d'une fonction personnalisée dans R : Calcul Gdd

Chafik J'ai besoin de ton aide s'il te plaît. Ma fonction doit prendre Tmin et Tmax, puis calcule gdd=(Tmin+Tmax)/2 et cumgdd=cumsum(gdd) pour chaque jour (ligne). si cummgdd<=356 , alors Tmin<0 = 0 & Tmax>21 = 21 si cumgdd >395 , alors Tmin<0 = 0 & Tmax<35 =3