Extracting data points from plots, images in IDL
Extracting data points from plots, images in IDL
(aka, "I've got this dang figure and can't get access to the original data (or at least not fast enough)... how do I extract the data points from the plot / image?")
So you would like to extract points from a figure and you have access to IDL? Well, you're lucky that I've written the code for it.
;+
; NAME:
; extract_points
;
; PURPOSE:
; To facilitate the extraction of data points from a JPEG figure.
;
; EXPLANATION:
; extract_points is pretty simple. It reads in a JPEG file,
; re-sizes it, and then prompts the user to do a bunch of
; clicking to define the axes and then select points to output.
;
; CALLING SEQUENCE:
; extract_points, file, out_arr $
; [, xsize=XSIZE, retain=RETAIN]
;
; INPUTS:
; file - a simple string that holds the JPEG filename.
;
; OUTPUT:
; out_arr - a n x 2 floating point array with n being the number
; of points the user clicked on.
;
; REVISION HISTORY:
; Written by: Joseph Lorenzo Hall, 18 Feb 2003.
;-
pro extract_points, file, out_arr, xsize=XSIZE, retain=RETAIN
read_jpeg, file, im ;READ IN JPEG
;RESIZE AND DISPLAY JPEG
if n_elements(xsize) ne 1 then $
x_pix = 640 else x_pix=xsize ;SET WINDOW SIZE
im_sz = size(im) ;GET IMAGE DIMENSIONS
jpg_type = im_sz[0]
if jpg_type eq 2 then begin ;8-BIT, 16-BIT
im_sz = size(im,/dim)
aspect = float(im_sz[1]) / float(im_sz[0]) ;ASPECT RATIO
new_im = congrid(im,x_pix,x_pix*aspect) ;RESIZE IMAGE
endif
if jpg_type eq 3 then begin ;24-BIT
im_sz = size(im,/dim)
aspect = float(im_sz[2]) / float(im_sz[1]) ;ASPECT RATIO
new_im = $
congrid(im,im_sz[0],x_pix,x_pix*aspect) ;RESIZE IMAGE
endif
window, retain=retain, xsize=x_pix, $ ;OPEN A SIZED WINDOW
ysize=x_pix*aspect
CASE StrUpCase(!D.Name) OF ;FANNING SUGGESTS THIS
'WIN': Device, Decomposed=1
'MAC': Device, Decomposed=1
'X' : Device, Decomposed=1
ELSE:
ENDCASE
if jpg_type eq 3 then tv, new_im, true=1
if jpg_type eq 2 then tv, new_im
;PROMPT TO CLICK ON A TICK LABELS ON X-AXIS
print, ' '
print, ' Please click on the FIRST labeled tick mark on the X-AXIS'
cursor, x1_x, x1_y, /normal, /down
print, ' Please enter the label of this tick mark:'
read, x1_val
print, ' Please click on the LAST labeled tick mark on the X-AXIS'
cursor, x2_x, x2_y, /normal, /down
print, ' Please enter the label of this tick mark:'
read, x2_val
;THE FOLLOWING ALLOWS A TRANFORMATION FROM NORMAL TO DATA COORDINATES
x_pix_diff = x2_x - x1_x
x_val_diff = x2_val - x1_val
x_scale = x_val_diff / x_pix_diff
x_int = x1_val - x1_x * x_scale
;PROMPT TO CLICK ON A TICK LABEL ON Y-AXIS
print, ' '
print, ' Please click on the FIRST labeled tick mark on the Y-AXIS'
cursor, y1_x, y1_y, /normal, /down
print, ' Please enter the label of this tick mark:'
read, y1_val
print, ' Please click on the LAST labeled tick mark on the Y-AXIS'
cursor, y2_x, y2_y, /normal, /down
print, ' Please enter the label of this tick mark:'
read, y2_val
y_pix_diff = y2_y - y1_y
y_val_diff = y2_val - y1_val
y_scale = y_val_diff / y_pix_diff
y_int = y1_val - y1_y * y_scale
cfx = [x_int,x_scale]
cfy = [y_int,y_scale]
repeat begin
print, ' '
print, ' Begin pixel input. Click on a data point to add it to your array.'
print, ' Click on middle or right button to exit.'
flag = 0
repeat begin
cursor, x, y, /normal, /down
if !mouse.button eq 1 then begin
if flag ne 1 then begin
flag = 1
x_arr = x & y_arr = y
endif else begin
x_arr = [x_arr,x] & y_arr = [y_arr,y]
endelse
endif
endrep until !mouse.button ge 2
npts = n_elements(x_arr)
as = sort(x_arr)
x_arr = x_arr(as) & y_arr = y_arr(as)
out_arr = fltarr(npts,2)
out_arr[*,0] = poly(x_arr,cfx)
out_arr[*,1] = poly(y_arr,cfy)
print, "Are you satisfied with your extraction (0=Sure am, 1=Nope)?"
read, ans
endrep until (ans eq 0)
end