2016-04-06 3 views
8

На самом деле я пытаюсь построить фигуру, но она помещает и показывает все столбцы (строки) друг на друга, поэтому она не является репрезентативной. Я пытаюсь сделать имитацию данные и показать вам, как я сюжет его, а также показать вам, что я хочукак рисовать фигуру с определенным расстоянием между каждой строкой

Я не знаю, как сделать данные, как например я показать ниже, но здесь то, что я делаю

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

Просьба представить данные в воспроизводимом формате – adaien

+0

Для четырех колонок это довольно просто, но я полагаю, что вы хотите применить это к большему количеству столбцов? – Laterow

+0

nvm, получил его thx – mtoto

ответ

8

Это решение использует rgl и производит этот сюжет:

enter image description here

Он использует эту функцию, которая принимает 3 аргумента:

  • df: a data.frame как ваш 'М' выше
  • x: a numeric vector (or a 1-col данные. frame ') для оси x
  • 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").

Черные линии, по умолчанию, могут создавать эффект moiré, но повторяющаяся цветовая палитра хуже. Это может быть зависимым от мозга. Единственный цвет также позволит избежать искусственного измерения (и сильного).

В качестве примера ниже:

# 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 окне можно перемещаться с помощью мыши.

Вам нужно что-то еще?


EDIT

Вы можете построить свой второй участок с функцией ниже. Диапазон ваших данных настолько велик, и я думаю, что вся идея сдвига вверх вверх по каждой линии предотвращает наличие оси Y с надежным масштабом. Здесь я нормализовал все сигналы (0 < = сигнал < = 1).Также можно использовать параметр gap. Мы могли бы отключить два поведения, но я думаю, что это хорошо. Попробуйте различные значения gap и посмотрите примеры ниже.

  • df: а data.frame так же, как ваш 'M' выше
  • x: а numeric vector (or a 1-col data.frame`) для оси х
  • cols: (optionnal) вектор цветов повторить. Если отсутствует, черная линия рисуется
  • gap: коэффициент разрыва между отдельными линиями
  • more_gap_each: каждые п линии, больший разрыв производится ...
  • more_gap_relative: ... и будет gap х 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 

И вы получите этот сюжет:

enter image description here

или:

nik_plot2D(M, x, 50) 

enter image description here

или, с цветами:

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 

enter image description here

+0

Можно ли сделать 2D-график, как указано выше? (каждый столбец с определенным расстоянием выше другого) – nik

+0

Вы имеете в виду примерно следующее: 'plot (x [, 1], M [, 5], type =" l ", xlab =" x title ", ylab = "y title") '? –

+0

Да, но только для одной колонки (профиля) смотрите выше фигуры. Я вставил в свой вопрос – nik

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, но график стал нечитаемым.

5

Как другие указали, ваши данные имеют очень большие пики и не ясно, хотите ли вы, чтобы некоторые кривые перекрываются,

enter image description here

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) 

enter image description here

(Есть, вероятно, хорошие алгоритмы, чтобы решить, какие точки необходимо удалить, но я не знаю их)

+0

Мне понравилось ваше решение, спасибо – nik

Смежные вопросы