## Get data from a graph on the screen. ## My use of this is to get data from scientific ## papers. In this case, you would have the PDF reader, ## or the scanned image on the screen, and get the points ## ## Usage ## [x,y]= get_graph_data([x axis labels],[y axis labels]) ## ## Example [x,y]=get_graph_data([1 10 100],[100,110,120,130]) ## - Then click with mouse #1 on 1, 10, 100, then mouse #2 or #3 ## - Then click with mouse #1 on 100, etc then mouse #2 or #3 ## - Then click on the data points ## ## Comments: ## - In windows, instead of mouse #1, position the mouse ## on the point and press . Press for mouse #2 or #3 ## - The function will automatically detect that the x-axis ## is in log units. ## - If you provide more x- or y- axis points, then the function ## will probably have a more accurate fit to the graph ## ## This program is in the public domain ## Author: Andy Adler function [x,y]= get_graph_data( xaxis, yaxis ) if nargin<2 usage('get_graph_data( xaxis, yaxis )'); end [xa_x, xa_y, xa_n, x_islog]= get_ax_points( xaxis, 'x axis'); [ya_x, ya_y, ya_n, y_islog]= get_ax_points( yaxis, 'y axis'); % Based on entered points, we want to see if the axis is % rotated (like in a scanned image, for example) x0= 0*xa_x; x1= x0+1; y0= 0*ya_x; y1= y0+1; X=[xa_x,xa_y,x1,x0; ya_x,ya_y,y0,y1]; Y=[xa_n,0*xa_n;0*ya_n,ya_n]; rot_ax= X\Y; % rot_x = [a,b;c,d; e,f;g,h] where % x intercept of y axis is f-h % y intercept of x axis is g-e irot= inv( rot_ax(1:2,:) ); ang1= [1 0]*irot; angx= 180/pi*atan2( ang1(2), ang1(1) ); yint= rot_ax(3,1) - rot_ax(4,1); printf('X axis is at %5.2f degrees and intercepts Y axis at %f\n', ... angx, yint ); ang1= [0 1]*irot; angy= 180/pi*atan2( ang1(2), ang1(1) ); xint= rot_ax(4,2) - rot_ax(3,2); printf('Y axis is at %5.2f degrees and intercepts X axis at %f\n', ... angy, xint ); printf('Select points to convert. Press Mouse #2 or #3 to quit\n'); fflush(stdout); [x,y]= grab(); % remove intercept locations rot_ax1= rot_ax(1:3,:); rot_ax1(3,2)=rot_ax(4,2); dconv= [x,y,x*0+1]*rot_ax1; x= dconv(:,1); if x_islog; x= 10.^x; end y= dconv(:,2); if y_islog; y= 10.^y; end function [a_x, a_y, a_n, islog]= get_ax_points( ax_pts, ax_text); printf(sprintf( ... 'click (with mouse #1) %s points, then (mouse #2)\n', ax_text)); fflush(stdout); [a_x,a_y]= grab(); if length(a_x) ~= length(ax_pts) error(sprintf('You specified %d %s points, but entered %d', ... length(ax_pts), ax_text, length(a_x) )); end islog= test_log( a_x, a_y, ax_pts, ax_text); if islog a_n= log10(ax_pts(:)); else a_n= ax_pts(:); end fflush(stdout); endfunction % Guess at whether axes are linear or logarithmic function ll=test_log( dx, dy, dfit, ax_text ) if any(dfit==0) printf(sprintf('GUESSING axis %s is LINEAR\n', ax_text)); ll=0; return end if length(dx)<3 printf(sprintf('Warning: Can t test fit using %d points', ... length(dx))) % try a heuristic test for linear if max(dfit)/min(dfit) < 10 printf(sprintf('GUESSING axis %s is LINEAR\n', ax_text)); ll=0; else printf(sprintf('GUESSING axis %s is LOGARITHMIC\n', ax_text)); ll=1; end return end dx= dx(:); dy=dy(:); dfit= dfit(:); [jnk, yf] = polyfit( dx, dfit, 1); dlinfit1= sumsq( dfit - yf ); [jnk, yf] = polyfit( dy, dfit, 1); dlinfit2= sumsq( dfit - yf ); dlinfit= min([dlinfit1, dlinfit2]); [jnk, yf] = polyfit( dx, log10(dfit), 1); dlogfit1= sumsq( log10(dfit) - yf ); [jnk, yf] = polyfit( dy, log10(dfit), 1); dlogfit2= sumsq( log10(dfit) - yf ); dlogfit= min([dlogfit1, dlogfit2]); if dlinfit < dlogfit printf(sprintf('axis %s is LINEAR\n', ax_text)); ll=0; else printf(sprintf('axis %s is LOGARITHMIC\n', ax_text)); ll=1; end fflush(stdout); endfunction