实际上我试图绘制一个数字,但它会放置并显示彼此之间的所有列(线),因此它不具代表性。我尝试制作模拟数据并向您展示我如何绘制它,并向您展示我想要的内容
我不知道如何制作如下所示的数据,但我在这里做什么
set.seed(1)
M <- matrix(rnorm(20),20,5)
x <- as.matrix(sort(runif(20, 5.0, 7.5)))
df <- as.data.frame(cbind(x,M))
在制作数据框之后,我将通过融合并使用ggplot来绘制所有列与第一列的关系
require(ggplot2)
require(reshape)
dff <- melt(df , id.vars = 'V1')
b <- ggplot(dff, aes(V1,value)) + geom_line(aes(colour = variable))
我想在每一行之间有特定的距离(在这种情况下我们有6),如下所示。在一个维度,它是V1,在另一个维度,它是列的数量。我不关心这个功能,我只想要照片
答案 0 :(得分:8)
此解决方案使用rgl
并生成此图:
它使用这个接受3个参数的函数:
df
:data.frame
就像上面的“M”一样x
:x轴的numeric vector (or a 1-col
data.frame`)cols
:( optionnal)要重复的颜色矢量。如果缺少,则绘制黑线这是功能:
nik_plot <- function(df, x, cols){
require(rgl)
# if a data.frame is
if (is.data.frame(x) && ncol(x)==1)
x <- as.numeric(x[, 1])
# prepare a vector of colors
if (missing(cols))
cols <- rep_len("#000000", nrow(df))
else
cols <- rep_len(cols, nrow(df))
# initialize an empty 3D plot
plot3d(NA, xlim=range(x), ylim=c(1, ncol(df)-1), zlim=range(df), xlab="Mass/Charge (M/Z)", ylab="Time", zlab="Ion Spectra", box=FALSE)
# draw lines, silently
silence_please <- sapply(1:ncol(df), function(i) lines3d(x=x, y=i, z=df[, i], col=cols[i]))
}
请注意,您可以从函数中删除require(rgl)
,并在脚本中的某处删除library(rgl)
,例如在开头。
如果您没有安装rgl
,则install.packages("rgl")
。
默认情况下,黑色线条可能会产生一些莫尔纹效果,但重复的调色板会更糟。这可能是依赖于大脑的。单一颜色也可以避免引入人造尺寸(和强烈的尺寸)。
以下示例:
# black lines
nik_plot(M, x)
# as in the image above
nik_plot(M, x, "grey40")
# an unreadable rainbow
nik_plot(M, x, rainbow(12))
可以使用鼠标导航3D窗口。
你还需要其他东西吗?
修改强>
您可以使用下面的功能构建第二个绘图。您的数据范围非常大,我认为每条线向上移动的整个想法都会阻止y轴具有可靠的比例。这里我已经对所有信号进行了归一化(0 <=信号&lt; = 1)。参数gap
也可以用来玩这个。我们可以断开这两种行为,但我认为这很好。请尝试gap
的不同值,并参阅下面的示例。
df
:data.frame
就像上面的“M”一样x
:x轴的numeric vector (or a 1-col
data.frame`)cols
:( optionnal)要重复的颜色矢量。如果缺少,则绘制黑线gap
:各行之间的差距因素more_gap_each
:每n行,就会产生更大的差距...... more_gap_relative
:...并且gap
x more_gap_relative
宽这是功能:
nik_plot2D <- function(df, x, cols, gap=10, more_gap_each=1, more_gap_relative=0){
if (is.data.frame(x) && ncol(x)==1)
x <- as.numeric(x[, 1])
# we normalize ( 0 <= signal <= 1)
df <- df-min(df)
df <- (df/max(df))
# we prepare a vector of colors
if (missing(cols))
cols <- rep_len("#00000055", nrow(df))
else
cols <- rep_len(cols, nrow(df))
# we prepare gap handling. there is probably more elegant
gaps <- 1
for (i in 2:ncol(df))
gaps[i] <- gaps[i - 1] + 1/gap + ifelse((i %% more_gap_each) == 0, (1/gap)*more_gap_relative, 0)
# we initialize the plot
plot(NA, xlim=range(x), ylim=c(min(df), 1+max(gaps)), xlab="Time", ylab="", axes=FALSE, mar=rep(0, 4))
axis(1)
# finally, the lines
silent <- lapply(1:ncol(df), function(i) lines(x, df[, i] + gaps[i], col=cols[i]))
}
我们可以使用它(默认):
nik_plot2D(M, x) # gap=10
你得到这个情节:
或:
nik_plot2D(M, x, 50)
或者,用颜色:
nik_plot2D(M, x, gap=20, cols=1:3)
nik_plot2D(M, x, gap=20, cols=rep(1:3, each=5))
或仍然有颜色,但间隙较大:
nik_plot2D(M, x, gap=20, cols=terrain.colors(10), more_gap_each = 1, more_gap_relative = 0) # no gap by default
nik_plot2D(M, x, gap=20, cols=terrain.colors(10), more_gap_each = 10, more_gap_relative = 4) # large gaps every 10 lines
nik_plot2D(M, x, gap=20, cols=terrain.colors(10), more_gap_each = 5, more_gap_relative = 2) # small gaps every 5 lines
答案 1 :(得分:5)
正如其他人所指出的,你的数据有很大的峰值,你不清楚是否要允许某些曲线重叠,
m <- read.table("~/Downloads/M.txt", head=T)
fudge <- 0.05
shifty <- function(m, fudge=1){
shifts <- fudge * max(abs(apply(m, 2, diff))) * seq(0, ncol(m)-1)
m + matrix(shifts, nrow=nrow(m), ncol=ncol(m), byrow=TRUE)
}
par(mfrow=c(1,2), mar=c(0,0,1,0))
cols <- colorRampPalette(blues9[4:9])(ncol(m))
matplot(shifty(m), t="l", lty=1, bty="n", yaxt="n", xaxt="n", ylab="", col=cols)
title("no overlap")
matplot(shifty(m, 0.05), t="l", lty=1, bty="n", yaxt="n", xaxt="n", ylab="", col=cols)
title("some overlap")
或者,在计算曲线之间的偏移之前,可以使用一些异常值/峰值检测方案对其进行滤波,
library(outliers)
shifty2 <- function(m, outliers = 10){
tmp <- m
for(ii in seq_len(outliers)) tmp <- rm.outlier(tmp, median = TRUE)
shifts <- max(abs(apply(tmp, 2, diff))) * seq(0, ncol(m)-1)
m + matrix(shifts, nrow=nrow(m), ncol=ncol(m), byrow=TRUE)
}
matplot(shifty2(m), t="l", lty=1, bty="n", yaxt="n", xaxt="n", ylab="", col=cols)
(可能有很好的算法来决定删除哪些点,但我不知道它们)
答案 2 :(得分:0)
对于3D绘图,我更喜欢rgl包。这应该接近您期望的解决方案 每次扫描的颜色每三分之一就会发生变化。
library(rgl)
M<-read.table("M.txt", sep="\t", header = TRUE, colClasses = "numeric")
x<-read.table("x.txt", sep="\t", header = TRUE)
n<-ncol(M)
M[M<1]<-1
plot3d(x='', xlim=range(x$Time), ylim=c(1, n), zlim=(range(M)), box=FALSE)
sapply(seq(1,n), function(t){lines3d(x$Time, y=t*10, z=(M[,t])/10000, col=t/3+1)})
title3d(xlab="scan", ylab="time", zlab="intensity")
title3d(main ="Extracted Spectra Subset")
axes3d()
#axis3d(edge="x")
#axis3d(edge="y")
#axis3d(edge="z")
数据点的幅度存在巨大差异,我需要扩展一些因素来制作可读的图形。强度从0到近1,000,000,从而扭曲图形。以ln为标准化,但情节变得难以理解。