如何为矩阵中的分类时间序列数据生成更好的图?

How to produce a nicer plot for my categorical time series data in a matrix?

我想在图形 window 的单独绘图上绘制此矩阵的每一行。

mat <- 
structure(c("g", "b", "c", "e", "g", "b", "g", "g", "e", "e", 
"a", "b", "b", "e", "c", "f", "d", "f", "g", "c", "f", "g", "b", 
"e", "a", "b", "c", "a", "c", "g", "c", "d", "e", "d", "b", "f", 
"e", "f", "a", "f", "c", "f", "e", "f", "d", "d", "f", "a", "d", 
"f"), .Dim = c(5L, 10L))

#     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
#[1,] "g"  "b"  "a"  "f"  "f"  "b"  "c"  "f"  "c"  "d"  
#[2,] "b"  "g"  "b"  "d"  "g"  "c"  "d"  "e"  "f"  "f"  
#[3,] "c"  "g"  "b"  "f"  "b"  "a"  "e"  "f"  "e"  "a"  
#[4,] "e"  "e"  "e"  "g"  "e"  "c"  "d"  "a"  "f"  "d"  
#[5,] "g"  "e"  "c"  "c"  "a"  "g"  "b"  "f"  "d"  "f"  

根据我的回答,我需要先将这个矩阵转换为数值。

v <- as.character(mat)
lev <- sort(unique(v))   ## sorted unique labels

# [1] "a" "b" "c" "d" "e" "f" "g"

mat_int <- matrix(match(v, lev), nrow = nrow(mat))

#     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
#[1,]    7    2    1    6    6    2    3    6    3     4
#[2,]    2    7    2    4    7    3    4    5    6     6
#[3,]    3    7    2    6    2    1    5    6    5     1
#[4,]    5    5    5    7    5    3    4    1    6     4
#[5,]    7    5    3    3    1    7    2    6    4     6

现在我正在使用以下代码生成我的图表。

par(mfrow=c(5,1))

matplot(t(mat_int)[, c(1)], yaxt = "n", type = "l", xlab = "time", ylab = "category")
axis(2, seq_along(lev), labels = lev)

matplot(t(mat_int)[, c(2)], yaxt = "n", type = "l", xlab = "time", ylab = "category")
axis(2, seq_along(lev), labels = lev)

matplot(t(mat_int)[, c(3)], yaxt = "n", type = "l", xlab = "time", ylab = "category")
axis(2, seq_along(lev), labels = lev)

matplot(t(mat_int)[, c(4)], yaxt = "n", type = "l", xlab = "time", ylab = "category")
axis(2, seq_along(lev), labels = lev)

matplot(t(mat_int)[, c(5)], yaxt = "n", type = "l", xlab = "time", ylab = "category")
axis(2, seq_along(lev), labels = lev)

但我有几个问题:

  1. 五个图中每个图的 y 轴上的标签仅包含部分结果(假设第二个图缺失 "a")。有没有一种方法可以列出所有五个图的 y 轴上的所有分类变量? (也就是说,每一个地块都有标签:a,b,c,d,e,f,g。
  2. 现在我必须在一个大页面上制作这个图,以便清楚地显示所有 y 轴标签。有没有什么办法可以将我的绘图更紧密地排列在一起以保存 space,以便它们可以放在较小的页面中?

谢谢。

我想指出3个问题。

这里使用plot

昨天在 R graphics: How to plot a sequence of characters (pure categorical time series) 中,您试图在单个图形上绘制 2 行或更多行的矩阵,所以我建议 matplot。但是现在你只想分别绘制不同的行,因此正常的 plot 就足够了。

随着您的更新,您可以使用

 plot(mat_int[2,], yaxt="n", type = "l", ylim = seq_along(lev), xlab = "time", ylab = "category")

设置一个普通的ylim

一旦您决定生成单独的图表,您需要设置一个通用的 ylim,以便 y-axis 可以在不同的图表之间进行比较。放

ylim = c(1, length(lev))

每个 plot 里面。请注意,ylim 采用长度为 2 的向量,给出最小值和最大值,因此 ylim = 1:length(lev) 是错误的。

调整绘图页边距和/或在更大的页面上绘图

R 图有两个边距。一个是图形 window 的外边距,另一个是内边距。边距以两种单位测量:线和英寸。相关图形参数为:

oma: *o*uter *ma*rgin in lines
omi: *o*uter *m*argin in *i*nches
mar: inner *mar*gin in lines
mai: inner *ma*rgin in *i*nches

通常以行为单位更方便,因为 x-axis 标签、绘图标题等按行放置,因此使用 omamar 而不是 omimai 让我们更好地了解如何根据需要设置边距。所有参数都采用长度为 4 的向量,在 "bottom"、"left"、"top"、"right" 上留出余量,即从底部顺时针方向。

通常你不需要对外边距做任何事情,它们默认都是零。您可以通过 par(c("oma","omi")) 来查看。请注意,将打开一个新的图形 window,但您可以忽略它或根据需要将其关闭。不唤醒是无法查询图形参数的 window,见grab par values without opening a graphics device?.

我们想将"top"、"bottom"处的内边距设置为0,这样所有的地块就会垂直拼接在一起。通过这样做,我们必须在 "top" 和 "bottom" 处设置外边距,以便为轴和标题留出一些额外的 space(如果需要)。

new_par <- old_par <- par(c("mar", "oma"))
new_par$mar[1] <- 0; new_par$mar[3] <- 0    ## inner bottom and top margin to 0
new_par$oma[1] <- 3; new_par$oma[3] <- 3    ## outer bottom and top margin to 3
par(new_par)    ## set new par

par(mfrow = c(5,1))

plot(mat_int[1, ], yaxt = "n", type = "l", xlab = "time", ylab = "category",
     xaxt = "n", ylim = c(1, length(lev)))
axis(3, axTicks(3))    ## place an x-axis on the top
axis(2, seq_along(lev), labels = lev)
axis(1, axTicks(1), labels = NA)    ##  draw ticks, but no labels

plot(mat_int[2, ], yaxt = "n", type = "l", xlab = "time", ylab = "category",
     xaxt = "n", ylim = c(1, length(lev)))
axis(2, seq_along(lev), labels = lev)
axis(1, axTicks(1), labels = NA)

plot(mat_int[3, ], yaxt = "n", type = "l", xlab = "time", ylab = "category",
     xaxt = "n", ylim = c(1, length(lev)))
axis(2, seq_along(lev), labels = lev)
axis(1, axTicks(1), labels = NA)

plot(mat_int[4, ], yaxt = "n", type = "l", xlab = "time", ylab = "category",
     xaxt = "n", ylim = c(1, length(lev)))
axis(2, seq_along(lev), labels = lev)
axis(1, axTicks(1), labels = NA)

plot(mat_int[5, ], yaxt = "n", type = "l", xlab = "time", ylab = "category",
     ylim = c(1, length(lev)))
axis(2, seq_along(lev), labels = lev)