Issue
Lets say I have a simple 2D numpy array that I display with imshow()
:
import numpy as np
import random
import matplotlib.pyplot as plt
a = np.random.randint(2, size=(10,10))
im = plt.imshow(a, cmap='spring', interpolation='none', vmin=0, vmax=1, aspect='equal')
plt.show()
And I have another 2D numpy array, like so:
bnd = np.zeros((10,10))
bnd[2,3] = bnd[3,2:5] = bnd[4,3] = 1
bnd[6,6] = bnd[7,5:8] = bnd[8,6] = 1
plt.imshow(bnd)
plt.show()
How can I generate an outline of all the continuous values of "1" in bnd
and then overplot it on a
, so I get something like the following (I manually added the black lines in the example below)?
Solution
You can compute the borders of the mask by finding the starting and ending indices of consecutive ones and converting those to border segments with coordinates of the image.
Setting up the image and the mask
import numpy as np
import matplotlib.pyplot as plt
a = np.random.randint(2, size=(10,10))
plt.imshow(a, cmap='spring', interpolation='none', vmin=0, vmax=1, aspect='equal')
bnd = np.zeros((10,10))
kernel = [[0,1,0],
[1,1,1],
[0,1,0]]
bnd[2:5, 2:5] = bnd[6:9, 5:8] = kernel
Finding the indices and convert them to coordinates of the image
# indices to vertical segments
v = np.array(np.nonzero(np.diff(bnd, axis=1))).T
vs = np.repeat(v, 3, axis=0) - np.tile([[1, 0],[0, 0],[np.nan, np.nan]], (len(v),1))
# indices to horizontal segments
h = np.array(np.nonzero(np.diff(bnd, axis=0))).T
hs = np.repeat(h, 3, axis=0) - np.tile([[0, 1],[0, 0],[np.nan, np.nan]], (len(h),1))
# convert to image coordinates
bounds = np.vstack([vs,hs])
x = np.interp(bounds[:,1], plt.xlim(), (0, bnd.shape[1]))
y = np.interp(bounds[:,0], sorted(plt.ylim()), (0, bnd.shape[0]))
plt.plot(x, y, color=(.1, .1, .1, .6), linewidth=5)
plt.show()
Output
Answered By - Michael Szczesny
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.