Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Plot a 2D binary matrix as a line in matplotlib using plot?

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

like image 615
webCoder Avatar asked Aug 09 '26 22:08

webCoder


2 Answers

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-')

enter image description here

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]]

complexer situation

like image 61
werner Avatar answered Aug 12 '26 12:08

werner


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

like image 30
Tim Roberts Avatar answered Aug 12 '26 10:08

Tim Roberts



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!