Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Arrange points and lines in an r plot legend

Tags:

plot

r

legend

Is it possible to rearrange the legend of the following plot

plot(1,1, type="n")
legend("topleft", c("1", "2"), col=c("darkblue", "darkred"), pch = 1, bty = "n", horiz = T, lwd=1.25, cex=1.8)

to look like this ("point-line-point" pattern)? enter image description here

like image 632
ECII Avatar asked Aug 09 '15 05:08

ECII


People also ask

How do you set the position of a legend in R?

You can place the legend literally anywhere. To put it around the chart, use the legend. position option and specify top , right , bottom , or left . To put it inside the plot area, specify a vector of length 2, both values going between 0 and 1 and giving the x and y coordinates.

Which argument must be set with plotting function for Legend () to display the legends?

Arguments. the x and y co-ordinates to be used to position the legend. They can be specified by keyword or in any way which is accepted by xy.

How do I add a point to a line plot in R?

To add new points to an existing plot, use the points() function. The points function has many similar arguments to the plot() function, like x (for the x-coordinates), y (for the y-coordinates), and parameters like col (border color), cex (point size), and pch (symbol type).

What is Lty in legend in R?

line type (lty) can be specified using either text (“blank”, “solid”, “dashed”, “dotted”, “dotdash”, “longdash”, “twodash”) or number (0, 1, 2, 3, 4, 5, 6). Note that lty = “solid” is identical to lty=1.


2 Answers

Usually, if you want this level of control over plot elements, you'll have to do it manually with primitives (points(), lines()/segments(), text(), etc.) and careful calculations from the plot parameters (e.g. par('usr')). It's not easy. Here's an example of how this could be done:

point.line.point <- function(x1,y1,x2=x1,y2=y1,...) {
    points(c(x1,x2),c(y1,y2),...);
    segments(x1,y1,x2,y2,...);
};
legend.plp <- function(x,y,labels,col,linewidth=diff(par('usr')[1:2])/10,textgap=diff(par('usr')[1:2])/20,...) {
    comb <- cbind(labels,col);
    xc <- x;
    for (i in seq_len(nrow(comb))) {
        x2 <- xc+linewidth;
        point.line.point(xc,y,x2,col=comb[i,'col'],...);
        text(x2+textgap,y,comb[i,'labels'],...);
        xc <- x2+textgap*1.5+strwidth(comb[i,'labels']);
    };
};

plot(1,1,type="n");
legend.plp(par('usr')[1]+diff(par('usr')[1:2])/20,par('usr')[4]-diff(par('usr')[3:4])/20,1:2,c('darkblue','darkred'),font=2,cex=1.5);

plot

like image 162
bgoldst Avatar answered Oct 09 '22 13:10

bgoldst


Here is an alternative solution that is the opposite of elegant. It involves embedding a couple of plots (one per legend), and a great deal of manual manipulation (to set the 'legends' where you want them to be):

library(Hmisc)
data(mtcars)
#plots the one in blue
plot(mtcars$cyl, type="o", col="darkblue")
#plots the one in red
lines(mtcars$carb, type="o", col="darkred")
#name the legends
text(6.5,7, "Cyl", font=2)
text(14,7, "Carb", font=2)
#add the subplots, it's actually a normal plot wrapped around the subplot with the x and y positions
subplot(plot(c(1,0),c(1,1), xlab=NA, ylab=NA, xaxt="n", yaxt="n", col="darkblue", type="o", axes=FALSE), 3, 7)
subplot(plot(c(1,0),c(1,1), xlab=NA, ylab=NA, xaxt="n", yaxt="n", col="darkred", type="o", axes=FALSE), 10, 7)

That yields the following plot:

enter image description here

like image 39
erasmortg Avatar answered Oct 09 '22 15:10

erasmortg