I have a 2D matrix containing zeros and ones. The ones define a shape from which I want to plot its contour/edge on a matplotlib figure. The initial 2D binary matrix:
[[0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 1 1 1 1 1 0 0 0]
[0 0 0 1 1 1 1 1 0 0 0]
[0 0 0 1 1 1 1 1 0 0 0]
[0 0 0 1 1 1 1 1 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0]]
I found here the method to get the corresponding 2D binary matrix of the edge of the shape:
[[0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 1 1 1 1 1 0 0 0]
[0 0 0 1 0 0 0 1 0 0 0]
[0 0 0 1 0 0 0 1 0 0 0]
[0 0 0 1 1 1 1 1 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0]]
Using plt.imshow, I get the following result: enter image description here
How would you do to plot the ones in this matrix as a dotted line in a matplotlib figure using plt.plot() ? I would like to get this result: enter image description here
2 Answers 2
For more complex geometries than a rectangle you can use the ConvexHull from scipy.spatial:
#starting with the original data
data = [
[0,0,0,0,0,0,0,0,0,0,0]
,[0,0,0,1,1,1,1,1,0,0,0]
,[0,0,0,1,1,1,1,1,0,0,0]
,[0,0,0,1,1,1,1,1,0,0,0]
,[0,0,0,1,1,1,1,1,0,0,0]
,[0,0,0,0,0,0,0,0,0,0,0]]
#convert the data array into x-y coordinates
#assume (0,0) is the lower left corner of the array
def array_to_coords(data):
for y, line in enumerate(reversed(data)):
for x, point in enumerate(line):
if point == 1:
yield(x, y)
points = list(array_to_coords(data))
#plot the points, skip this if you only need the dotted line
x,y = zip(*points)
plt.plot(x, y, 'o')
plt.xlim(0,10)
plt.ylim(0,5)
#plot the convex hull
from scipy.spatial import ConvexHull
hull = ConvexHull(points)
for simplex in hull.simplices:
plt.plot(hull.points[simplex,0], hull.points[simplex,1], 'ro-')
A more complex situation:
data = [
[0,0,0,0,0,1,0,0,0,0,0]
,[0,0,0,1,1,1,1,1,0,0,0]
,[0,0,0,1,1,1,1,1,0,0,0]
,[0,0,0,1,1,1,1,1,0,0,0]
,[0,0,1,1,1,1,1,0,0,0,0]
,[0,0,0,0,0,0,0,0,0,0,0]]
Comments
This isn't exactly the same, but maybe it can give you a start. You can see what I did. I extracted the x,y locations of the 1 values, then plotted x against y in a scatter plot.
import matplotlib.pyplot as plt
import numpy as np
array = np.array(
[[0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,1,1,1,1,1,0,0,0],
[0,0,0,1,0,0,0,1,0,0,0],
[0,0,0,1,0,0,0,1,0,0,0],
[0,0,0,1,1,1,1,1,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0]])
coords = np.argwhere(array==1)
plt.xlim(0,10)
plt.ylim(0,5)
plt.scatter(coords[:,1],coords[:,0])
plt.show()
Output: enter image description here
Followup
import matplotlib.pyplot as plt
import numpy as np
array = np.array(
[[0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,1,1,1,1,1,0,0,0],
[0,0,0,1,0,0,0,1,0,0,0],
[0,0,0,1,0,0,0,1,0,0,0],
[0,0,0,1,1,1,1,1,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0]])
coords = np.argwhere(array==1)
xmin = np.min(coords[:,1])
xmax = np.max(coords[:,1])
ymin = np.min(coords[:,0])
ymax = np.max(coords[:,0])
x = [xmin,xmin,xmax,xmax,xmin]
y = [ymin,ymax,ymax,ymin,ymin]
plt.xlim(0,10)
plt.ylim(0,5)
plt.plot(x, y, '--')
plt.show()
Output: Second answer