A simple gnuplot digitizer?

Viewed 154

Sometimes it might be useful to digitize scanned graphs to get the data and redraw a plot. I'm aware that there are dedicated tools with a lot of features, e.g. see miscellaneous links on the gnuplot home page: http://gnuplot.info/links.html

However, is there maybe a way using gnuplot only? Maybe with a few lines of code you can implement a simple version of a digitizer? Which should already be sufficient for some cases having a limited number of datapoints.

(edit: part of original question now put as answer)

1 Answers

In case this might be useful to someone... this gnuplot version is just for fun, sharing and for demonstration of gnuplot capabilities. Improvements are welcome, e.g.

  • logarithmic axes, time axes, multiple curves, tilted images, etc.

How it works:

  • an image is imported into a graph. gnuplot supports e.g. GIF, JPG, PNG. To see the list of filetypes show datafile binary filetype.
  • the first 3 mouseclicks have to be on 1) end of y-axis, 2) origin, and 3) end of x-axis
  • further mouseclicks draw datapoints

The following key bindings are implemented:

  • 0 (re-)define the axes from end of y-axis to origin to end of x-axis
  • x remove all datapoints
  • c clear only last datapoint
  • s save data to file

Code:

### a simple gnuplot digitizer
reset session
 
IMAGE = 'Superconductivity.png'
DATAFILE = 'Digitized.dat'
 
OriginX = 4.00
OriginY = 0.00
AxisYEnd = 0.15
AxisXEnd = 4.40
 
DataHeader = '# Temperature Resistance'
set print $Data
    print DataHeader
set print
print $Data
 
$Axes <<EOD
EOD
 
set margins 0,0,0,0
AxesPoints = 0
 
fx(point) = (word(point,1)-word($Axes[2],1))/(word($Axes[3],1)-word($Axes[2],1))*(AxisXEnd - OriginX)+OriginX
fy(point) = (word(point,2)-word($Axes[2],2))/(word($Axes[1],2)-word($Axes[2],2))*(AxisYEnd - OriginY)+OriginY
 
bind Button1 '\
    if (AxesPoints<3) { set print $Axes append; print MOUSE_X, MOUSE_Y; AxesPoints=AxesPoints+1; replot; } \
    else { set print $Data append; print MOUSE_X, MOUSE_Y; set print; replot; }'
 
bind 0 'AxesPoints=0; set print $Axes; print ""; set print; replot;'
 
bind x 'set print $Data; print DataHeader; set print; replot'
 
bind c 'if (|$Data|>2) {array A[|$Data|]; do for [i=2:|$Data|-1] { A[i]=$Data[i] }; \
        set print $Data; do for [i=1:|A|-1] { print A[i] }; } \
        else {set print $Data; print DataHeader; }; set print; replot;'
 
bind s 'set print DATAFILE; print $Data[1]; set print DATAFILE append; \
        do for [i=2:|$Data|] { print sprintf("%g %g", fx($Data[i]), fy($Data[i])) }; \
        set print; pause -1 sprintf("Data saved to: %s",DATAFILE);'
 
plot IMAGE binary filetype=auto origin=(0,0) dx=1 dy=1 with rgbimage notitle, \
     $Axes u 1:2 w l lw 2 lc "blue" noautoscale not, \
     $Data u 1:2 w p pt 7 lc "red" noautoscale notitle
### end of code

Input: Superconductivity.png

enter image description here

Procedure: (Screen capture of wxt terminal)

enter image description here

Result: Digitized.dat

# Temperature Resistance
4.3696 0.130726
4.3328 0.126117
4.232 0.113966
4.20241 0.00157884
4.19248 0.000406976
4.18307 0.000751641
Related