Een legende tekenen buiten het tekengebied in basisafbeeldingen?

Zoals de titel al zegt: Hoe kan ik een legenda buiten het tekengebied plotten bij gebruik van basisafbeeldingen?

Ik dacht erover om te spelen met layouten een lege plot te maken om alleen de legenda te bevatten, maar ik zou geïnteresseerd zijn in een manier om alleen de basisgrafiekfaciliteiten te gebruiken en bijvoorbeeld par(mar = )om wat ruimte aan de rechterkant van de plot te krijgen voor de legende.


Hier een voorbeeld:

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

produceert:

Maar zoals gezegd, ik zou graag willen dat de legenda buiten het plotgebied staat (bijv. rechts van de grafiek/plot.


Antwoord 1, autoriteit 100%

Misschien heb je par(xpd=TRUE)nodig om dingen buiten het plotgebied te kunnen tekenen. Dus als je de hoofdplot met bty='L'doet, heb je wat ruimte aan de rechterkant voor een legenda. Normaal gesproken zou dit naar het plotgebied worden geknipt, maar doe par(xpd=TRUE)en met een beetje aanpassing kun je een legenda zo ver mogelijk naar rechts krijgen:

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

Antwoord 2, autoriteit 96%

Niemand heeft genoemd met behulp van negatieve insetwaarden voor legend. Hier is een voorbeeld, waarbij de legende rechts van de plot is, uitgelijnd met de bovenkant (met behulp van trefwoord "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")

De eerste waarde van inset=c(-0.2,0)Mogelijk moeten aanpassen op basis van de breedte van de legende.


Antwoord 3, Autoriteit 27%

Een andere oplossing, naast de al genoemde ONDES (met layoutof par(xpd=TRUE)) is om uw plot met een transparant plot over het hele apparaat te bedekken en Voeg dan de legende toe aan dat.

De truc is om een ​​(lege) grafiek over het volledige plotting gebied over te nemen en de legende aan dat toe te voegen. We kunnen de par(fig=...)-optie gebruiken. Eerst instrueren we R om een ​​nieuw plot te maken over het gehele plotapparaat:

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

Instelling omaEN maris nodig omdat we het interieur van het perceel het hele apparaat willen bedekken. new=TRUEis nodig om te voorkomen dat R een nieuw apparaat starten. We kunnen dan het lege perceel toevoegen:

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

en we staan ​​klaar om de legende toe te voegen:

legend("bottomright", ...)

voegt een legende toe aan de rechtsonder op het apparaat. Evenzo kunnen we de legende toevoegen aan de boven- of rechtermarge. Het enige dat we nodig hebben om ervoor te zorgen, is dat de marge van het oorspronkelijke perceel groot genoeg is om de legende te ontvangen.

Dit alles in een functie zetten;

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(...)
}

en een voorbeeld. Maak eerst de plot die ervoor zorgt dat we aan de onderkant genoeg ruimte hebben om de legende toe te voegen:

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

Voeg vervolgens de legende

toe

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

resulterend in:


Antwoord 4, Autoriteit 14%

Sorry voor het opruïneren van een oude draad, maar ik was vandaag met hetzelfde probleem. De eenvoudigste manier waarop ik heb gevonden, is het volgende:

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

Hier gevonden: http://www.harding.edu/fmcCown/r/


Antwoord 5, Autoriteit 12%

Ik vind het leuk om het zo te doen:

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

De enige vereiste aanpassing is in het vaststellen van de juiste marge om breed genoeg te zijn om de legende te huisvesten.

Dit kan echter ook worden geautomatiseerd:

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


Antwoord 6, Autoriteit 8%

Ik kan alleen een voorbeeld van de lay-outoplossing aanbieden die al opmerkt.

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


Antwoord 7, Autoriteit 8%

Onlangs vond ik een zeer eenvoudige en interessante functie om de legende buiten het plotgebied te printen, waar u maar wilt.

Maak de buitenmarge aan de rechterkant van de plot.

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

Maak een perceel

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

Legenda toevoegen en gebruik gewoon Locator (1) -functie zoals hieronder. Dan moet u gewoon klikken waar u zoekt na het volgen van het script.

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

Probeer het


Antwoord 8, autoriteit 7%

Nog een eenvoudig alternatief toevoegen dat naar mijn mening behoorlijk elegant is.

Uw plot:

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

Legende:

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

Resultaat:

Hier is alleen de tweede regel van de legenda aan uw voorbeeld toegevoegd. Op zijn beurt:

  • inset=c(0,1)– verplaatst de legenda per fractie van het plotgebied in (x,y) richtingen. In dit geval bevindt de legenda zich op de positie "bottomright". Het wordt verplaatst door 0 plotgebieden in x-richting (dus blijft op “rechts”) en door 1 plotgebied in y-richting (van onder naar boven). En het gebeurt zo dat het precies boven de plot verschijnt.
  • xpd=TRUE– laat de legenda buiten het plotgebied verschijnen.
  • horiz=TRUE– geeft opdracht om een horizontale legenda te maken.
  • bty="n"– een stijldetail om het begrenzingsvak voor legenda’s te verwijderen.

Hetzelfde geldt voor het toevoegen van een legenda aan de zijkant:

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

Hier hebben we eenvoudig de legendeposities aangepast en extra marge-ruimte aan de rechterkant van de plot toegevoegd. Resultaat:


Antwoord 9, Autoriteit 3%

U kunt dit doen met de plotte R API , met ofwel code, of van de GUI door slepen de legende waar je het wilt.

Hier is een voorbeeld. De grafiek en -code zijn ook hier .

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)

U kunt de legende buiten de grafiek plaatsen door een van de X- en Y-waarden toe te wijzen aan 100 of -100.

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

Hier zijn de andere opties:

  • list("x" = 100, "y" = 0)VOOR BUITEN RECHTSE BUTOM
  • list("x" = 100, "y"= 1)BUITEN RECHTSE TOP
  • list("x" = 100, "y" = .5)BUITEN RECHTS MIDDEN
  • list("x" = 0, "y" = -100)onder links
  • list("x" = 0.5, "y" = -100)ONDER CENTER
  • list("x" = 1, "y" = -100)ONDER RECHTS

Dan het antwoord.

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

Grotly retourneert een URL met uw grafiek wanneer u belt. U kunt dat sneller openen door browseURL(response$url)te bellen, zodat u uw grafiek in uw browser voor u opent.

url = response$url
filename = response$filename

Dat geeft ons deze grafiek. U kunt de legenda ook vanuit de GUI verplaatsen, waarna de grafiek overeenkomstig wordt geschaald. Volledige openbaarmaking: ik zit in het Plotly-team.


Antwoord 10, autoriteit 2%

Probeer layout()die ik hiervoor in het verleden heb gebruikt door simpelweg een lege plot hieronder te maken, op de juiste manier geschaald op ongeveer 1/4 of zo en de onderdelen van de legenda er handmatig in te plaatsen.

Er zijn hier enkele oudere vragen over legend()waarmee u aan de slag kunt.

Other episodes