【问题标题】:ggplot for objects stored in an 3D arrayggplot 用于存储在 3D 数组中的对象
【发布时间】:2021-02-03 19:19:36
【问题描述】:

我已经编写了以下代码,它正在工作并绘制我想要的东西,但是如果我想使用 ggplot 进行绘图,我该怎么做呢?

myseq<-seq(from = 1, to = 99, by = 5)
mtx <- array(rnorm(880,0,1) ,c(4,11,length(myseq)))

plot(myseq,mtx[1,1,],type = "l", col=1) 
lines(myseq,mtx[1,2,],type = "l",col=2)
lines(myseq,mtx[1,3,],type = "l",col=3)
lines(myseq,mtx[1,4,],type = "l",col=4)
lines(myseq,mtx[1,5,],type = "l",col=5)
lines(myseq,mtx[1,6,],type = "l",col=6)
lines(myseq,mtx[1,7,],type = "l",col=7)
lines(myseq,mtx[1,8,],type = "l",col=8)
lines(myseq,mtx[1,9,],type = "l",col=9)
lines(myseq,mtx[1,10,],type = "l",col=10)
lines(myseq,mtx[1,11,],type = "l",col=11)

运行此语句后,我得到如下图,现在如何使用 ggplot2 来做这件事?

enter image description here

【问题讨论】:

  • threshold 19 吗?
  • 当我运行此代码时(将 19 替换为 threshold),我没有得到那个图,我得到关于向量长度的错误。当我将 myseq 更改为长度 19 时(推断它应该与数组的其中一个暗角配对),然后我得到一个看起来完全不同的图。也许我是教条主义的,但是......如果你要说你从代码中得到一个情节,也许你可以使用你给我们的代码?
  • 很好的编辑。请注意,因为您将一个包含 836 个随机数的数组填充到 4*11*20 (880) 的维度中,所以您正在回收 44 个随机数。这不会改变绘制它的方式,但如果这与您的真实过程非常相似,那么您的数据就会被破坏/有偏差。
  • 对不起。我已经改变了我的问题主题,提供的错误现在已经消失了。
  • 4*11*19 因为myseq的长度是19。

标签: r list ggplot2 plot line


【解决方案1】:

ggplot2 更喜欢数据帧,对于这样的东西,帧格式较长。

这是一个基本的方法。

首先,可重现的随机数据。

set.seed(42)
myseq<-seq(from = 1, to = 99, by = 5)
mtx <- array(rnorm(880,0,1) ,c(4,11,length(myseq)))
mtx[1,1:4,1:4]
#            [,1]       [,2]       [,3]          [,4]
# [1,]  1.3709584 -1.3682810  0.9333463  6.288407e-05
# [2,]  0.4042683 -0.4314462  0.6503486 -1.173196e-01
# [3,]  2.0184237  1.5757275 -1.1317387 -8.610730e-02
# [4,] -1.3888607  0.6792888  1.2009654 -4.138688e-01

从这里,我们基本上可以将这个3D数组转换成四列data.frame,其中三列表示轴,第四列是实际值。

melted_mtx <- reshape2::melt(mtx[1,,,drop=FALSE])
str(melted_mtx, vec.len=15)
# 'data.frame': 220 obs. of  4 variables:
#  $ Var1 : int  1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ...
#  $ Var2 : int  1 2 3 4 5 6 7 8 9 10 11 1 2 3 4 5 6 7 8 9 10 11 1 2 3 4 5 6 7 8 9 10 11 1 2 3 4 5 ...
#  $ Var3 : int  1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 ...
#  $ value: num  1.371 0.404 2.018 -1.389 -0.284 -0.307 1.895 0.46 1.035 -0.784 0.206 -1.368 -0.431 1.576 0.679 -0.367 -0.727 0.921 0.624 ...

由于您想在 x 轴上绘制 myseq,我们可以用它进行替换。它在第三个变量中,Var3。我会验证它的长度是否正确,然后进行替换:

lapply(melted_mtx[-4], table)
# $Var1
#   1 
# 220 
# $Var2
#  1  2  3  4  5  6  7  8  9 10 11 
# 20 20 20 20 20 20 20 20 20 20 20 
# $Var3
#  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 
# 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 

melted_mtx$Var3 <- myseq[melted_mtx$Var3]
lapply(melted_mtx[-4], table)
# $Var1
#   1 
# 220 
# $Var2
#  1  2  3  4  5  6  7  8  9 10 11 
# 20 20 20 20 20 20 20 20 20 20 20 
# $Var3
#  1  6 11 16 21 26 31 36 41 46 51 56 61 66 71 76 81 86 91 96 
# 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 

我们可以使用它并将其直接提供给ggplot2

library(ggplot2)
ggplot(melted_mtx, aes(Var3, value, group = Var2, color = factor(Var2))) +
  geom_line()

该(您的代码)呈现的基本图形图:

除了边距和颜色之外,实际上是相同的情节。可以做很多美化,包括图例标签、轴等。

上面,我只melted 数组的第一个平面。如果你做了整个数组,那么它看起来像这样:

melted_mtx <- reshape2::melt(mtx)
melted_mtx$Var3 <- myseq[melted_mtx$Var3]
ggplot(melted_mtx, aes(Var3, value, group = interaction(Var1, Var2),
                       color = interaction(Var1, Var2))) +
  geom_line()

显然,这有点复杂,但是使用interaction,您可以按多个变量进行分组。这里需要分组,因为没有它ggplot2 将尝试将所有点连接在一条线上,通常没有用。通常可以使用 just color= 来建议组,但我经常同时包括 group=color= 以防我以后更改颜色/线型/形状/...被定义,组被意外更改。

【讨论】:

  • 我不能在 X 轴上绘制 myseq 吗?我不太了解 reshape 包。
  • 这里我知道myseq的长度是绘制在x轴上的。
  • 这应该是一个简单的“替换”操作,因为数组该维度上的索引也是(根据数组的定义)myseq 上的索引。查看我的编辑。
  • 非常感谢。这非常有帮助。现在我必须找到一种方法以重复功能运行整个事情。我不知道 ggplot 将所有对象存储为全局字符。一直在尝试aes里面的melted_mtx$Var3,melted_mtx$value,看看吧。
  • 如果您的问题已经解决,请accept the answer。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-23
  • 2011-09-24
  • 2020-08-21
  • 2016-05-21
  • 1970-01-01
  • 2011-11-11
相关资源
最近更新 更多