This is a walk through of the widgets yoink provides to facilitate pulling line data from a rasterized image. Sometimes the canned extraction routines will not be sufficiently flexible to deal with your data. The hope is that this walk-though is broken into enough pieces and sufficiently explicit for you to steal the pieces you need for your application.
For the benefit of folks readng this on the web, the walk-though will display each figure at each stage in the extraction. It is worth noting that Yoink requires interactive figures and is incompatible with embedded IPython figures (though the webAgg backend may fix this).
In [1]:
%pylab
import pylab as plt
import numpy as np
from yoink.widgets import ShutterCrop, DeformableLine
In [2]:
plt.figure(1)
plt.clf()
X = np.linspace(0, 7, 100)
Y = np.sinc(X)
plt.plot(X, Y)
plt.title('original data')
plt.show()
plt.savefig('sinc.png')
img = plt.imread('sinc.png')
In [3]:
plt.gcf()
Out[3]:
In [4]:
plt.figure(2)
plt.clf()
plt.imshow(img)
cropper = ShutterCrop(plt.gca())
plt.title('Cropping')
Out[4]:
In [5]:
plt.gcf()
Out[5]:
The cropper gives you the extents (in pixel coordinate) of the edges of your embedded figure. Make a new image with only these pixels.
In [6]:
ext = cropper.get_extents()
j0, jx = sorted(ext[:2])
i0, ix = sorted(ext[2:])
img_crop = img[i0:ix+1, j0:jx+1]
In [7]:
plt.figure(3)
plt.clf()
plt.imshow(img_crop)
xl = plt.xlim()
yl = plt.ylim()
line = DeformableLine(gca())
plt.xlim(*xl)
plt.ylim(*yl)
plt.title('Pick Points (pixel coordinates)')
Out[7]:
In [8]:
plt.gcf()
Out[8]:
Now that you've selected your data, you need to convert it from pixel coordinates to the scale in the original figure. Here we interpolate between axis extremes.
Note the indexing. img_crop has shape (ny, nx, nc) ny is the number of vertical pixels, nx is the number of horizontal pixels. nc is the number of color channels. Also notice that PNG's use the top left as the origin. So we had to flip the ymin/ymax order.
Finally, we plot the original data X, Y along with the picked data x, y to show that they overlay.
In [9]:
plt.figure(4)
plt.clf()
plt.title('rescale points to actual data scale')
xmin, xmax = 0, 7
ymin, ymax = -0.4, 1.2
ny, nx, nc = img_crop.shape
x = np.interp(line.xs, [0, nx], [xmin, xmax])
y = np.interp(line.ys, [0, ny], [ymax, ymin])
plt.plot(x, y, 'bo-', label='Picked')
plt.plot(X, Y, 'r', label='Original')
plt.legend(loc='upper right')
Out[9]:
In [10]:
plt.gcf()
Out[10]:
In [ ]: