プロット画像からデータを復元


論文のプロットから元データを推定したかったのでごにょごにょした.

image2data <- function(file, xmin,xmax, ymin,ymax){
  ## file: 画像ファイル名
  ## xmin, xmax: x軸の最小,最大値
  ## ymin, ymax: y軸の最小,最大値
  
  ## 要EBImage
  im <- readImage(file)
  ## 座標取得(プレビュー逆さになるけど戻すとおかしくなる…)
  oldpar <- par(mar=rep(0,4))
  image(1:nrow(im), 1:ncol(im), im, axes=FALSE)
  loc <- lapply(locator(2), function(x) round(sort(x)))
  par(oldpar)
  ## 取得した座標範囲を対象に
  im <- im[loc$x[1]:loc$x[2], loc$y[1]:loc$y[2]]
  ## 値が0.5以下の点(黒いとこ)の座標を取得
  nx <- nrow(im); ny <- ncol(im)
  x <- y <- numeric(0)
  ## indexを実際の値に対応づける
  rx <- seq(xmin, xmax, len=nx)
  ry <- seq(ymin, ymax, len=ny)
  cnt <- 1
  for(i in 1:nx){
    if(length(hit <- (1:ny)[im[i, 1:ny] < 0.5])>0){
      x[cnt:(cnt + length(hit) - 1)] <- rx[i]
      y[cnt:(cnt + length(hit) - 1)] <- ry[ny - hit + 1]
      cnt <- cnt+length(hit)
    }
  }
  return(data.frame(x, y))
}

画像の読み込みにBioconductorのEBImageを使ったので,

source("http://bioconductor/biocLite.R")
bioLite("EBImage")

としてEBImageをインストールしておく.また別途ImageMagicとgtkが必要なのでどこかで入手してインストールとPATHの設定を済ませておく.(参考: http://www.eml.ele.cst.nihon-u.ac.jp/~momma/wiki/wiki.cgi/R/R%e3%81%a7%e7%94%bb%e5%83%8f%e8%a7%a3%e6%9e%90(EBImage%e7%b7%a8).html)
インストールしたら

library(EBImage)

としてEBImageパッケージを読み込んでおくのを忘れずに.

ソース中にも書いてあるけど引数は

  • file: ファイルへのパス
  • xmin, xmax: x軸の値の左端の値,右端の値
  • ymin, ymax: y軸の値の下端の値,上端の値

実行すると画像が逆さにプレビューされるてlocator(2)が実行されるので*1,軸を含まないように気をつけてプロットの枠内の左上と右下,または左下と右上の2点をクリックする.
そうすると色が濃かった場所の座標がデータフレームになってまとめて返ってくる.

冒頭に示した画像は以下のコードを実行したもの.

## imageの読み込みはEBImageを使う
library(EBImage)
## データ準備
png(file="sin.png", width=500, height=300)
curve(sin, 0, 5)
dev.off()
## テスト
plot(image2data("sin.png", 0, 5, -1, 1), type="l")
display(readImage("sin.png"))

時間かかるので何かあたまがわるいやり方をしている可能性がなきにしもあらず.

*1:画像の読み込みにEBImageのreadImage使ってる関係でひっくりかえる.多分ちょっといじれば直せるけど面倒そうだから考えてもいない