web-dev-qa-db-fra.com

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

Comme le titre le dit: Comment puis-je tracer une légende en dehors de la zone de traçage lorsque j'utilise des graphiques de base?

Je pensais jouer avec layout et produire un tracé vide ne contenant que la légende, mais je serais intéressé de manière à utiliser uniquement les facilités graphiques de base et, par exemple, par(mar = ) pour obtenir de l'espace sur le à 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:

alt text

Mais comme dit, je voudrais que la légende soit en dehors de la zone de traçage (par exemple, à droite du graphique/tracé).

161
Henrik

Peut-être avez-vous besoin de par(xpd=TRUE) pour permettre de dessiner des éléments en dehors de la région de l'intrigue. Donc, si vous faites l'intrigue principale avec bty='L', vous aurez un peu de place à droite pour une légende. Normalement, ceci serait coupé à la région du tracé, mais faites par(xpd=TRUE) et avec un peu d'ajustement, vous pouvez obtenir une légende aussi à droite 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))
101
Spacedman

Personne n'a mentionné l'utilisation de valeurs négatives inset pour legend. Voici un exemple où la légende se trouve à droite du tracé, alignée en haut (à l'aide du 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

133
Mike T

Une autre solution, outre les ondes déjà mentionnées (en utilisant layout ou par(xpd=TRUE)) consiste à superposer votre tracé à un tracé transparent sur tout le périphérique, puis à y ajouter la légende.

L'astuce consiste à superposer un graphique (vide) sur toute la zone de traçage 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)

Il est nécessaire de définir oma et mar car nous souhaitons que l’intérieur du tracé couvre tout le périphérique. 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 dans la marge supérieure ou droite. La seule chose que nous devons nous assurer est que la marge de la parcelle d'origine soit suffisamment grande pour accueillir la légende.

Mettre tout cela dans une 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 Commencez par créer le tracé en vous assurant que vous disposez de 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)

Ajoutez ensuite 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:

Example figure shown legend in top margin

26
Jan van der Laan

J'aime le faire comme ça:

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))

enter image description here

La seule modification nécessaire consiste à définir la marge droite de manière à ce que la légende soit suffisamment large.

Cependant, cela peut aussi ê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))

enter image description here

15
jbaums

Désolé d'avoir ressuscité un ancien fil de discussion, mais le même problème se posait aujourd'hui. Le moyen le plus simple que j'ai trouvé est le suivant:

# 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é ici: http://www.harding.edu/fmccown/R/

14
veiga

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

Faire 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 une 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")

Ajoutez une légende et utilisez simplement le localisateur (1) comme ci-dessous. Ensuite, il vous suffit de 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))

L'essayer

9
Vandka

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))

an ugly picture :S

8
Roman Luštrik

Ajouter 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:

picture with legend

Ici, seule 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 la région du tracé dans les directions (x, y). Dans ce cas, la légende est à la position "bottomright". Il est déplacé par 0 région de tracé dans la direction x (reste donc à "droite") et par 1 région de tracé dans la direction y (de bas en haut). Et il se trouve qu'il apparaît juste au-dessus de l'intrigue.
  • xpd=TRUE - la légende apparaît en dehors de la zone de traçage.
  • horiz=TRUE - indique la production d'une légende horizontale.
  • bty="n" - un détail de style permettant de supprimer le cadre 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 des légendes et ajouté une marge supplémentaire à droite du graphique. Résultat:

picture with legend 2

5

Vous pouvez le faire avec le Plotly R API , avec le code ou depuis l'interface graphique en faisant glisser la légende à l'endroit souhaité.

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 affectant l'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) Extérieur Droite Haut
  • list("x" = 100, "y" = .5) Extérieur Droite Milieu
  • list("x" = 0, "y" = -100) Sous la gauche
  • list("x" = 0.5, "y" = -100) Sous Centre
  • list("x" = 1, "y" = -100) Sous Droite

Puis la réponse.

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

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

url = response$url
filename = response$filename

Cela nous donne ce graphique. Vous pouvez également déplacer la légende depuis l'interface graphique, puis le graphique sera mis à l'échelle en conséquence. Divulgation complète: je fais partie de l'équipe Plotly.

Legend on side of graph

4
Mateo Sanchez

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

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

2
Dirk Eddelbuettel