График для сравнения двух матриц в R - PullRequest
2 голосов
/ 22 сентября 2010

У меня есть две матрицы (приблизительно 300 x 100), и я хотел бы построить график, чтобы увидеть части первой, которые выше, чем у второй.

Я могу сделать, дляinstance:

# Calculate the matrices and put them into m1 and m2
# Note that the values are between -1 and 1
par(mfrow=c(1,3))
image(m1, zlim=c(-1,1))
image(m2, zlim=c(-1,1))
image(m1-m2, zlim=c(0,1))

Это позволит отобразить только нужные области на 3-м графике, но я бы хотел сделать что-то немного другое, например, провести линию вокруг этих областей над первым графиком, чтобы выделить их напрямуютам.

Есть идеи, как мне это сделать?

Спасибо, Нико

Ответы [ 3 ]

2 голосов
/ 22 сентября 2010

Как насчет:

par(mfrow = c(1, 3))
image(m1, zlim = c(-1, 1))
contour(m1 - m2, add = TRUE)
image(m2, zlim = c(-1, 1))
contour(m1 - m2, add = TRUE)
image(m1 - m2, zlim = c(0, 1))
contour(m1 - m2, add = TRUE)

Это добавляет контурную карту вокруг регионов. Сортировка колец вокруг областей 3-го графика (возможно, вы захотите поиграть с (n) уровнями контуров, чтобы получить меньше «кругов»).

1 голос
/ 23 сентября 2010

Вот код, который я написал, чтобы сделать что-то подобное. Я хотел выделить смежные области выше порога 0,95, нарисовав вокруг них прямоугольник, поэтому я получил все квадраты сетки выше 0,95 и сделал кластеризацию на них. Затем немного поэкспериментируйте с выходом кластеризации, чтобы получить координаты прямоугольника областей:

computeHotspots = function(xyz, thresh, minsize=1, margin=1){
### given a list(x,y,z), return a data frame where each row
### is a (xmin,xmax,ymin,ymax) of bounding box of a contiguous area
### over the given threshhold.
### or approximately. lets use the clustering tools in R...

  overs <- which(xyz$z>thresh,arr.ind=T)

  if(length(overs)==0){
    ## found no hotspots
    return(NULL)
  }

  if(length(overs)==2){
    ## found one hotspot
    xRange <- cbind(xyz$x[overs[,1]],xyz$x[overs[,1]])
    yRange <- cbind(xyz$y[overs[,2]],xyz$y[overs[,2]])
  }else{

    oTree <- hclust(dist(overs),method="single")
    oCut <- cutree(oTree,h=10)

    oXYc <- data.frame(x=xyz$x[overs[,1]],y=xyz$y[overs[,2]],oCut)

    xRange <- do.call("rbind",tapply(oXYc[,1],oCut,range))
    yRange <- do.call("rbind",tapply(oXYc[,2],oCut,range))

  }

### add user-margins
 xRange[,1] <- xRange[,1]-margin
 xRange[,2] <- xRange[,2]+margin
 yRange[,1] <- yRange[,1]-margin
 yRange[,2] <- yRange[,2]+margin

## put it all together
 xr <- apply(xRange,1,diff)
 xm <- apply(xRange,1,mean)
 xRange[xr<minsize,1] <- xm[xr<minsize]-(minsize/2)
 xRange[xr<minsize,2] <- xm[xr<minsize]+(minsize/2)

 yr <- apply(yRange,1,diff)
 ym <- apply(yRange,1,mean)
 yRange[yr<minsize,1] <- ym[yr<minsize]-(minsize/2)
 yRange[yr<minsize,2] <- ym[yr<minsize]+(minsize/2)

  cbind(xRange,yRange)

}

Тестовый код:

x=1:23
y=7:34
m1=list(x=x,y=y,z=outer(x,y,function(x,y){sin(x/3)*cos(y/3)}))
image(m1)
hs = computeHotspots(m1,0.95)

Это должно дать вам матрицу прямоугольных координат:

> hs
  [,1] [,2] [,3] [,4]
1   13   15    8   11
2    3    6   17   20
3   22   24   18   20
4   13   16   27   30

Теперь вы можете нарисовать их поверх изображения с помощью прямоугольника:

image(m1)
rect(hs[,1],hs[,3],hs[,2],hs[,4])

и показать, где они должны быть:

image(list(x=m1$x,y=m1$y,z=m1$z>0.95))
rect(hs[,1],hs[,3],hs[,2],hs[,4])

Конечно, вы могли бы адаптировать это, чтобы рисовать круги, но более сложные формы были бы хитрыми. Это работает лучше всего, когда области интересов довольно компактны.

Barry

1 голос
/ 22 сентября 2010

Другой способ создания вашего третьего изображения может быть следующим:

image(m1>m2)

. В результате получается матрица значений ИСТИНА / ЛОЖЬ, которая отображается как 0/1, поэтому у вас есть двухцветное изображение.Тем не менее, вы все еще не уверены в том, что вам нужно «поставить линию вокруг» ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...