; ; Datathief for IDL Ralph Lorenz ; LPL, University of Arizona ; ; ; ; V1.0 seems to work - send to selected grad students for testing ; ; Datathief is a tool for generating people- or machine- ; readable lists of numbers from an image of a graph. This is ; useful, for example, to compare your model or data with ; published datapoints ; ; This code is not smart enough to work out the points for itself - ; the user has to click on them manually. Datathief was originally ; implemented (in a much more polished fashion) on the Macintosh in ; a shareware code. As I (and many others) use workstations, I ; finally got round to coding this up, trivial as it is. I welcome ; more elaborate versions (how about a widget-controlled version, ; someone ?) ; ; PROCEDURE ; ; Scan in your graph. Manipulate using your favourite image tool like xv ; or Photoshop - get the x-axis horizontal and the y-axis vertical. If ; saved as a positive image (black text on white) IDL will display as ; white text on black and vice-versa, so invert it if desired with the ; image tool. Save as a GIF file ; ; invoke IDL. Load the datathief code (this file) with the command ; .run datathief ; ; load the image with the command LOADIM, FILENAME1 ; where the FILENAME1 is the name of the image file (e.g. 'graph.gif') ; ; now set the axes. Datathief assumes that the axes are orthogonal. The axes ; do not need to cross (i.e. if there are multiple axes on the graph, it can ; handle that) ; ; If the x-axis runs 0 to 100, say, type XAXIS,0.,100. ; (don't forget the periods, to force IDL to use floating point arithmetic) ; ; if the axis is logarithmic, say 0.1 to one million, just add the flag /LOG ; i.e. XAXIS, 0.1, 1.0e6, /LOG ; ; you need to click (left button) on the corresponding points on the x-axis ; ; then do the same for the y-axis YAXIS,0.,100 (or whatever) ; ; now the axes are set ; ; to digitize the datapoints type POINTS, N, FILENAME2 ; ; where N is the number of points (sorry I haven't set it up to be interactive - ; just pick a number that will be big enough - click on dummy points if it's ; too many and edit the resultant datafile afterwards if desired) and FILENAME2 ; is the name of the datafile you want the results (which will also appear on ; screen) e.g. 'enemydata.txt' ; ; Click away over the datapoints, and lo - you should see a list of data generated, ; ready for incorporation into your own figures ; ; IDL will remember the axis settings until you change them, so say there are two sets ; of symbols on the graph, you would set the axes, then run POINTS twice, and the two ; sets of data can be saved in separate files. If there are two (or more) sets of data, ; with different Y-axes, say, you can change the Y-axis settings in between, etc. ; pro loadim, imfile common data, im, xmin, xmax, ymin, ymax, $ x1,x2,x3,x4,y1,y2,y3,y4, xlog,ylog read_gif,imfile, im xrr=size(im) xr=xrr(1) yr=xrr(2) window,0, xsize=xr, ysize=yr tvscl,im end pro xaxis, xi, xa, LOG=log common data xmax=xa xmin=xi xlog=0 if keyword_set(log) then begin xlog=1 endif print,'Click on Left-Hand End of X-axis' cursor,x1,y1, /down, /device x1=1.0*x1 print,'Click on Right-Hand End of X-axis' cursor,x2,y2, /down, /device x2=1.0*x2 end pro yaxis, yi, ya, LOG=log common data ymax=ya ymin=yi ylog=0 if keyword_set(log) then begin ylog=1 endif print,'Click on Bottom End of Y-axis' cursor,x3,y3, /down, /device y3=1.0*y3 print,'Click on Top End of Y-axis' cursor,x4,y4, /down, /device y4=1.0*y4 end pro points, num, outfile common data xs=fltarr(num) ys=fltarr(num) print,'Click on Points' for i=0,num-1 do begin cursor,x,y,/down, /device if (xlog gt 0) then begin xs(i)=xmin * ((xmax/xmin)^((x-x1)/(x2-x1))) endif else begin xs(i)=xmin + (xmax-xmin)*(x-x1)/(x2-x1) endelse if (ylog gt 0) then begin ys(i)=ymin * ((ymax/ymin)^((y-y3)/(y4-y3))) endif else begin ys(i)=ymin + (ymax-ymin)*(y-y3)/(y4-y3) endelse print,i,xs(i),ys(i) endfor openw,1,outfile for i=0,num-1 do begin printf,1,xs(i),ys(i) endfor close,1 end