I have a data frame with 4 columns, all floating-point numbers. I would like to make a piecewise-line plot. Each curve will have 4 points, 1 curve per row of the dataframe. The x-values should be the values of the dataframe, the y-values the column indices.
In Python I would have done something like this
plt.figure()
for i in range(data.shape[0]):
plt.plot(data[i], [0,1,2,3], '*-')
plt.show()
I have spent an hour reading forums and trying out different arguments for matplot
and ggplot
but to no avail.
Here is the result of my python plot
I don't mind using other libraries like ggplot2 or other.
Edit: I forgot to specify an important additional requirement. All of the curves have to be sorted in the order of their column index. For example, consider the following plot
Here, the 3rd curve is not plotted correctly with respect to this additional requirement. Its y-indices go in the order [0, 2, 1, 3], whereas it should be [0, 1, 2, 3]. It is the X-axis that I would like to not be sorted.
CodePudding user response:
Obviously, in Base R this is just the same as in Python.
clr <- hcl.colors(ncol(m)) ## define colors
plot.new(); plot.window(xlim=range(m), ylim=c(0, 3)) ## define plot area
for (i in seq_len(ncol(m))) lines(m[, i], 0:3, type='o', pch=20, col=clr[i]) ## loop
axis(1); axis(2); box() ## axes and box
Data:
set.seed(42)
m <- sapply(0:10, \(i) c(-.5, .5, 1.5, 2.5) i rnorm(4, 0, .1))
CodePudding user response:
A ggplot2
approach would require to first reshape your data to long using e.g. tidy::pivot_longer
.
Using some fake example data
library(ggplot2)
library(tidyr)
library(dplyr, warn = FALSE)
dat <- data.frame(
"0" = seq(-1, 2, length.out = 10),
"1" = 1 seq(-1, 2, length.out = 10),
"2" = 2 seq(-1, 2, length.out = 10),
"3" = 3 seq(-1, 2, length.out = 10),
check.names = FALSE
)
dat
#> 0 1 2 3
#> 1 -1.0000000 0.0000000 1.000000 2.000000
#> 2 -0.6666667 0.3333333 1.333333 2.333333
#> 3 -0.3333333 0.6666667 1.666667 2.666667
#> 4 0.0000000 1.0000000 2.000000 3.000000
#> 5 0.3333333 1.3333333 2.333333 3.333333
#> 6 0.6666667 1.6666667 2.666667 3.666667
#> 7 1.0000000 2.0000000 3.000000 4.000000
#> 8 1.3333333 2.3333333 3.333333 4.333333
#> 9 1.6666667 2.6666667 3.666667 4.666667
#> 10 2.0000000 3.0000000 4.000000 5.000000
dat |>
mutate(id = row_number()) |>
pivot_longer(-id,
names_to = "y", values_to = "x"
) |>
mutate(y = as.numeric(y)) |>
ggplot(aes(x, y, color = factor(id)))
geom_line()
geom_point()