如何绘制每条线之间具有特定距离的图形

nik*_*nik 8 r

实际上我试图绘制一个图,但它放置并显示彼此的所有列(线),因此它不具有代表性.我尝试制作模拟数据并向您展示我如何绘制它,并向您展示我想要的内容

我不知道如何制作如下所示的示例数据,但这里是我做的

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))
Run Code Online (Sandbox Code Playgroud)

在创建数据框之后,我将通过熔化并使用ggplot来绘制所有列与第一个列的关系

require(ggplot2)
require(reshape)
dff <- melt(df ,  id.vars = 'V1')
b <- ggplot(dff, aes(V1,value)) + geom_line(aes(colour = variable))
Run Code Online (Sandbox Code Playgroud)

我想在每一行之间有特定的距离(在这种情况下我们有6),如下所示.在一个维度,它是V1,在另一个维度,它是列的数量.我不关心功能,我只想要照片

Vin*_*mme 8

此解决方案使用rgl并生成此图:

在此输入图像描述

它使用此函数接受3个参数:

  • df :data.frame就像你上面的'M'一样
  • x :numeric vector (or a 1-colx轴的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])) 
}
Run Code Online (Sandbox Code Playgroud)

请注意,您可以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))
Run Code Online (Sandbox Code Playgroud)

可以使用鼠标导航3D窗口.

您还需要些别的吗?


编辑

您可以使用下面的功能构建第二个绘图.您的数据范围如此之大,我认为每条线向上移动的整个想法都会阻止y轴具有可靠的比例.这里我对所有信号进行了归一化(0 <=信号<= 1).此参数gap也可用于播放.我们可以断开这两种行为,但我认为这很好.尝试不同的值gap并查看下面的示例.

  • df :data.frame就像你上面的'M'一样
  • x :numeric vector (or a 1-colx轴的data.frame`)
  • cols:(optionnal)要重复的颜色矢量.如果缺少,则绘制黑线
  • gap :各行之间的差距因素
  • more_gap_each:每n行,产生更大的差距......
  • more_gap_relative:...并且将是gapx 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]))
}
Run Code Online (Sandbox Code Playgroud)

我们可以使用它(默认):

nik_plot2D(M, x) # gap=10
Run Code Online (Sandbox Code Playgroud)

你得到这个情节:

在此输入图像描述

要么:

nik_plot2D(M, x, 50)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

或者,用颜色:

nik_plot2D(M, x, gap=20, cols=1:3)
nik_plot2D(M, x, gap=20, cols=rep(1:3, each=5))
Run Code Online (Sandbox Code Playgroud)

或者,仍然有颜色但间隙较大:

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
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


bap*_*ste 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")
Run Code Online (Sandbox Code Playgroud)

或者,在计算曲线之间的偏移之前,可以使用一些异常值/峰值检测方案对其进行滤波,

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)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

(可能有很好的算法来决定删除哪些点,但我不知道它们)