Tracer une légende en dehors de la zone de traçage dans les graphiques de base?

Comme le titre l'indique: Comment puis-je tracer une légende en dehors de la zone de tracé lors de l'utilisation de graphiques de base?

J'ai pensé à jouer avec layout et à produire un tracé vide pour ne contenir que la légende, mais je serais intéressé par une manière d'utiliser uniquement les fonctionnalités du graphique de base et par exemple, par(mar = ) pour obtenir de l'espace à droite de l'intrigue pour la légende.


Voici un exemple:

plot(1:3, rnorm(3), pch = 1, lty = 1, type = "o", ylim=c(-2,2))
lines(1:3, rnorm(3), pch = 2, lty = 2, type="o")
legend(1,-1,c("group A", "group B"), pch = c(1,2), lty = c(1,2))

Produit:

le texte d'alt

, Mais comme dit, je voudrais la légende pour être en dehors de la zone de tracé (par exemple, à droite du graphique/tracé.

144
demandé sur Henrik 2010-10-14 14:01:44

10 réponses

Peut-être que ce dont vous avez besoin est par(xpd=TRUE) pour permettre aux choses d'être dessinées en dehors de la région de l'intrigue. Donc, si vous ne l'intrigue principale avec bty='L' vous aurez de l'espace sur la droite pour une légende. Normalement, cela serait coupé à la région de l'intrigue, mais faites par(xpd=TRUE) et avec un peu d'ajustement, vous pouvez obtenir une légende aussi loin que possible:

 set.seed(1) # just to get the same random numbers
 par(xpd=FALSE) # this is usually the default

 plot(1:3, rnorm(3), pch = 1, lty = 1, type = "o", ylim=c(-2,2), bty='L')
 # this legend gets clipped:
 legend(2.8,0,c("group A", "group B"), pch = c(1,2), lty = c(1,2))

 # so turn off clipping:
 par(xpd=TRUE)
 legend(2.8,-1,c("group A", "group B"), pch = c(1,2), lty = c(1,2))
92
répondu Spacedman 2013-09-12 15:04:18

Personne n'a mentionné l'utilisation de valeurs inset négatives pour legend. Voici un exemple, où la légende est à droite de l'intrigue, alignée vers le haut (en utilisant le mot-clé "topright").

# Random data to plot:
A <- data.frame(x=rnorm(100, 20, 2), y=rnorm(100, 20, 2))
B <- data.frame(x=rnorm(100, 21, 1), y=rnorm(100, 21, 1))

# Add extra space to right of plot area; change clipping to figure
par(mar=c(5.1, 4.1, 4.1, 8.1), xpd=TRUE)

# Plot both groups
plot(y ~ x, A, ylim=range(c(A$y, B$y)), xlim=range(c(A$x, B$x)), pch=1,
               main="Scatter plot of two groups")
points(y ~ x, B, pch=3)

# Add legend to top right, outside plot region
legend("topright", inset=c(-0.2,0), legend=c("A","B"), pch=c(1,3), title="Group")

La première valeur de inset=c(-0.2,0) peut nécessiter un ajustement en fonction de la largeur de la légende.

legend_right

122
répondu Mike T 2012-05-10 05:36:05

Une autre solution, outre les ondes déjà mentionnées (en utilisant layout ou par(xpd=TRUE)) est de superposer votre tracé avec un tracé transparent sur l'ensemble du périphérique, puis d'ajouter la légende à cela.

L'astuce consiste à superposer un graphique (vide) sur la zone de traçage complète et à y ajouter la légende. Nous pouvons utiliser l'option par(fig=...). Nous demandons d'abord à R de créer un nouveau tracé sur l'ensemble du dispositif de traçage:

par(fig=c(0, 1, 0, 1), oma=c(0, 0, 0, 0), mar=c(0, 0, 0, 0), new=TRUE)

Paramètre oma et mar est nécessaire, car nous voulons avoir l'intérieur de l'intrigue couvrir l'ensemble du dispositif. new=TRUE est nécessaire pour empêcher R de démarrer un nouveau périphérique. Nous pouvons ensuite ajouter le tracé vide:

plot(0, 0, type='n', bty='n', xaxt='n', yaxt='n')

Et nous sommes prêts à ajouter la légende:

legend("bottomright", ...)

Ajoutera une légende en bas à droite de l'appareil. De même, nous pouvons ajouter la légende à la marge supérieure ou à droite. La seule chose que nous devons nous assurer est que la marge de l'intrigue originale est assez grande pour accueillir la légende.

Mettre tout cela dans un fonction;

add_legend <- function(...) {
  opar <- par(fig=c(0, 1, 0, 1), oma=c(0, 0, 0, 0), 
    mar=c(0, 0, 0, 0), new=TRUE)
  on.exit(par(opar))
  plot(0, 0, type='n', bty='n', xaxt='n', yaxt='n')
  legend(...)
}

Et un exemple. Créez d'abord l'intrigue en vous assurant que nous avons suffisamment d'espace en bas pour ajouter la légende:

par(mar = c(5, 4, 1.4, 0.2))
plot(rnorm(50), rnorm(50), col=c("steelblue", "indianred"), pch=20)

, Puis ajoutez la légende

add_legend("topright", legend=c("Foo", "Bar"), pch=20, 
   col=c("steelblue", "indianred"),
   horiz=TRUE, bty='n', cex=0.8)

, Résultant en:

Exemple figure illustrée légende dans la marge supérieure

21
répondu Jan van der Laan 2014-02-14 16:06:31

Désolé d'avoir ressuscité un vieux fil, mais j'étais avec le même problème aujourd'hui. La façon la plus simple que j'ai trouvée est la suivante:

# Expand right side of clipping rect to make room for the legend
par(xpd=T, mar=par()$mar+c(0,0,0,6))

# Plot graph normally
plot(1:3, rnorm(3), pch = 1, lty = 1, type = "o", ylim=c(-2,2))
lines(1:3, rnorm(3), pch = 2, lty = 2, type="o")

# Plot legend where you want
legend(3.2,1,c("group A", "group B"), pch = c(1,2), lty = c(1,2))

# Restore default clipping rect
par(mar=c(5, 4, 4, 2) + 0.1)

Trouvés ici: http://www.harding.edu/fmccown/R/

12
répondu veiga 2011-10-24 18:02:43

J'aime le faire comme ceci:

par(oma=c(0, 0, 0, 5))
plot(1:3, rnorm(3), pch=1, lty=1, type="o", ylim=c(-2,2))
lines(1:3, rnorm(3), pch=2, lty=2, type="o")
legend(par('usr')[2], par('usr')[4], bty='n', xpd=NA,
       c("group A", "group B"), pch=c(1, 2), lty=c(1,2))

entrez la description de l'image ici

Le seul peaufinage nécessaire est de définir la marge de droite pour être assez large pour accueillir la légende.

Cependant, cela peut également être automatisé:

dev.off() # to reset the graphics pars to defaults
par(mar=c(par('mar')[1:3], 0)) # optional, removes extraneous right inner margin space
plot.new()
l <- legend(0, 0, bty='n', c("group A", "group B"), 
            plot=FALSE, pch=c(1, 2), lty=c(1, 2))
# calculate right margin width in ndc
w <- grconvertX(l$rect$w, to='ndc') - grconvertX(0, to='ndc')
par(omd=c(0, 1-w, 0, 1))
plot(1:3, rnorm(3), pch=1, lty=1, type="o", ylim=c(-2, 2))
lines(1:3, rnorm(3), pch=2, lty=2, type="o")
legend(par('usr')[2], par('usr')[4], bty='n', xpd=NA,
       c("group A", "group B"), pch=c(1, 2), lty=c(1, 2))

entrez la description de l'image ici

11
répondu jbaums 2016-01-06 02:49:22

Je ne peux offrir qu'un exemple de la solution de mise en page déjà indiquée.

layout(matrix(c(1,2), nrow = 1), widths = c(0.7, 0.3))
par(mar = c(5, 4, 4, 2) + 0.1)
plot(1:3, rnorm(3), pch = 1, lty = 1, type = "o", ylim=c(-2,2))
lines(1:3, rnorm(3), pch = 2, lty = 2, type="o")
par(mar = c(5, 0, 4, 2) + 0.1)
plot(1:3, rnorm(3), pch = 1, lty = 1, ylim=c(-2,2), type = "n", axes = FALSE, ann = FALSE)
legend(1, 1, c("group A", "group B"), pch = c(1,2), lty = c(1,2))

une image laide: S

7
répondu Roman Luštrik 2010-10-14 11:01:00

Récemment, j'ai trouvé une fonction très facile et intéressante pour imprimer la légende en dehors de la zone de l'intrigue où vous voulez.

Faites la marge extérieure sur le côté droit de la parcelle.

par(xpd=T, mar=par()$mar+c(0,0,0,5))

Créer un tracé

plot(1:3, rnorm(3), pch = 1, lty = 1, type = "o", ylim=c(-2,2))
lines(1:3, rnorm(3), pch = 2, lty = 2, type="o")

Ajoutez une légende et utilisez simplement la fonction locator (1) comme ci-dessous. Ensuite, vous devez simplement cliquer où vous voulez après le chargement du script suivant.

legend(locator(1),c("group A", "group B"), pch = c(1,2), lty = c(1,2))

Essayez-le

7
répondu Vandka 2017-12-11 02:40:24

Vous pouvez le faire avec l'API Plotly R , soit avec du code, soit à partir de L'interface graphique en faisant glisser la légende où vous le souhaitez.

Voici un exemple. Le graphique et le code sont également ici.

x = c(0,1,2,3,4,5,6,7,8) 
y = c(0,3,6,4,5,2,3,5,4) 
x2 = c(0,1,2,3,4,5,6,7,8) 
y2 = c(0,4,7,8,3,6,3,3,4)

Vous pouvez positionner la légende en dehors du graphique en attribuant une des valeurs x et y à 100 ou -100.

legendstyle = list("x"=100, "y"=1)
layoutstyle = list(legend=legendstyle)

Voici les autres options:

  • list("x" = 100, "y" = 0) pour L'extérieur en bas à droite
  • list("x" = 100, "y"= 1) À L'Extérieur En Haut À Droite
  • list("x" = 100, "y" = .5) Extérieur Droit Milieu
  • list("x" = 0, "y" = -100) Sous La Gauche
  • list("x" = 0.5, "y" = -100) Sous Le Centre
  • list("x" = 1, "y" = -100) Sous La Droite

Puis la réponse.

response = p$plotly(x,y,x2,y2, kwargs=list(layout=layoutstyle));

Renvoie Plotly une URL avec votre graphique lorsque vous effectuez un appel. Vous pouvez y accéder plus rapidement en appelant browseURL(response$url) afin qu'il ouvre votre graphique dans votre navigateur pour vous.

url = response$url
filename = response$filename

Cela nous donne ce graphique. Vous pouvez également déplacer la légende à partir de l'interface graphique, puis le graphique évoluera conséquent. Divulgation complète: je suis dans L'équipe Plotly.

Légende sur le côté du graphique

3
répondu Mateo Sanchez 2014-01-20 21:20:14

Essayez layout() que j'ai utilisé pour cela dans le passé en créant simplement un tracé vide ci-dessous, correctement mis à l'échelle autour de 1/4 ou plus et en y plaçant les parties de légende manuellement.

Il y a quelques questions plus anciennes ici à propos de legend() qui devraient vous aider à démarrer.

1
répondu Dirk Eddelbuettel 2010-10-14 10:17:27

Ajout d'une autre alternative simple qui est assez élégante à mon avis.

Votre parcelle:

plot(1:3, rnorm(3), pch = 1, lty = 1, type = "o", ylim=c(-2,2))
lines(1:3, rnorm(3), pch = 2, lty = 2, type="o")

Légende:

legend("bottomright", c("group A", "group B"), pch=c(1,2), lty=c(1,2),
       inset=c(0,1), xpd=TRUE, horiz=TRUE, bty="n"
       )

Résultat:

image avec légende

Ici que la deuxième ligne de la légende a été ajoutée à votre exemple. À son tour:

  • inset=c(0,1) - déplace la légende par fraction de région du tracé dans les directions (x, y). Dans ce cas, la légende est à la position "bottomright". Il est déplacé de 0 régions de tracé dans la direction x (donc reste à "droite") et de 1 tracé région dans la direction y (de bas en haut). Et il se trouve qu'il apparaît juste au-dessus de l'intrigue.
  • xpd=TRUE - laissez la légende apparaître en dehors de la région de traçage.
  • horiz=TRUE - indique de produire une légende horizontale.
  • bty="n" - un détail de style pour se débarrasser de la boîte englobante de légende.

La même chose s'applique lors de l'ajout d'une légende sur le côté:

par(mar=c(5,4,2,6))
plot(1:3, rnorm(3), pch = 1, lty = 1, type = "o", ylim=c(-2,2))
lines(1:3, rnorm(3), pch = 2, lty = 2, type="o")

legend("topleft", c("group A", "group B"), pch=c(1,2), lty=c(1,2),
       inset=c(1,0), xpd=TRUE, bty="n"
       )

Ici, nous avons simplement ajusté les positions de légende et ajouté un espace de marge supplémentaire sur le côté droit de l'intrigue. Résultat:

image avec légende 2

0
répondu Karolis Koncevičius 2018-03-26 22:00:05