R: Line plotting in a simpler shorter way

I'm doing some line plotting. I have this matrix:

  [,1] [,2] [,3]
1  0.1  0.2  0.3
2  0.5  1.0  1.5
3  1.0  1.5  2.0
4  1.5  2.0  2.5

And I compute the L1 norm of each matrix column. So the norm for each column will be [1] 3.1 4.7 6.3 the L1 norm will be the x-axis. Each Matrix row will be the y-axis.

So, for x [1] 3.1 4.7 6.3 and y 0.1 0.2 0.3 I plot one line.

For x [1] 3.1 4.7 6.3 and y 0.5 1.0 1.5 I plot another line line, and so on.

Here is the code, which does it:

mat=matrix(c(0.1,0.5, 1, 1.5, 0.2, 1, 1.5 ,2,0.3, 1.5, 2, 2.5), nrow=4, ncol=3)
rownames(mat) <- seq_len(nrow(mat))
norm1=as.vector(rep(0,3))
for (i in 1:3) {
  norm1[i]=norm(as.matrix(mat[,i]))   
}
y1=c(0.1, 0.2, 0.3)
y2=c(0.5,1.0,1.5)
y3=c(1.0,1.5,2)
y4=c(1.5,2,2.5)
plot(norm1,y1, type = "l", xlim=c(3,7), ylim=c(0,3)) 
lines(norm1,y2)
lines(norm1,y3)
lines(norm1,y4) 

Is there any other way how I could do the plotting simpler and shorter? If I would have a matrix 100x20 I would have to write for each row a y1=c(0.1, 0.2, 0.3) and add to many lines(norm1,y4).

And here is the plot: enter image description here

2 answers

  • answered 2018-03-13 21:15 r2evans

    Sure:

    # automated lims here, you can easily override
    plot(NA, xlim=range(norm1), ylim=range(mat))
    for (r in seq_len(nrow(mat))) lines(norm1, mat[r,])
    

  • answered 2018-03-13 21:48 Maurits Evers

    Here is a tidyverse solution:

    L1 <- function(x) sum(abs(x));
    bind_cols(
        as.data.frame(mat) %>%
            summarise_all(funs(L1(.))) %>%
            t() %>%
            as.data.frame() %>%
            rename(x = V1),
        t(mat) %>%
            as.data.frame() %>%
            rename_all(funs(gsub("V", "", .)))) %>%
        gather(row, y, 2:5) %>%
        ggplot(aes(x, y, colour = row)) + geom_line();
    

    enter image description here