Reputation: 21533
I just want to draw simple shape by points, like this:
import matplotlib.pyplot as plt
rectangle = [(0,0),(0,1),(1,1),(1,0)]
hexagon = [(0,0),(0,1),(1,2),(2,1),(2,0),(1,-1)]
l_shape = [(0,0),(0,3),(1,3),(1,1),(3,1),(3,0)]
concave = [(0,0),(0,3),(1,3),(1,1),(2,1),(2,3),(3,3),(3,0)]
for points in [rectangle, hexagon, l_shape, concave]:
# 1. Can I get rid of the zip? plot directly by points
# 2. How can I make the shape complete?
xs, ys = zip(*points)
plt.plot(xs, ys, 'o')
plt.plot(xs, ys, '-')
automin, automax = plt.xlim()
plt.xlim(automin-0.5, automax+0.5)
automin, automax = plt.ylim()
plt.ylim(automin-0.5, automax+0.5)
# Can I display the shapes 2 in 1 line?
plt.show()
My question is
*zip
? I mean, directyly draw by points, rather than 2 array.complete
? Since I'm looping through all the points, the first and last cannot connect together, how can I do it?convex hull
?)Upvotes: 6
Views: 8476
Reputation: 25339
The code below doesn't use temporary variables xs
and ys
, but a direct tuple unpacking. Also I add first point from points
list to make shapes complete.
rectangle = [(0,0),(0,1),(1,1),(1,0)]
hexagon = [(0,0),(0,1),(1,2),(2,1),(2,0),(1,-1)]
l_shape = [(0,0),(0,3),(1,3),(1,1),(3,1),(3,0)]
concave = [(0,0),(0,3),(1,3),(1,1),(2,1),(2,3),(3,3),(3,0)]
for points in [rectangle, hexagon, l_shape, concave]:
plt.plot(*zip(*(points+points[:1])), marker='o')
automin, automax = plt.xlim()
plt.xlim(automin-0.5, automax+0.5)
automin, automax = plt.ylim()
plt.ylim(automin-0.5, automax+0.5)
plt.show()
Provide this answer as an alternative leekaiinthesky's post
Upvotes: 1
Reputation: 5593
To close the shape, just add the first point again at the end of the list:
# rectangle = [(0,0),(0,1),(1,1),(1,0)]
rectangle = [(0,0),(0,1),(1,1),(1,0),(0,0)]
plt.plot
takes a list of x coordinates and a list of y coordinates. I would say that the way you're doing it now is already the way of doing it "by points rather than 2 arrays". Because if you wanted to do it without zip
, it would look like this:
rectangleX = [0, 0, 1, 1, 0]
rectangleY = [0, 1, 1, 0, 0]
plt.plot(rectangleX, rectangleY, 'o')
plt.plot(rectangleX, rectangleY, '-')
Update:
For better polygon support, use the patches module [example]. This may be more along the lines of what you're looking for. By default (closed = True
), it will close the path for you, and it also allows you to add vertices directly to a list (not two separate lists):
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
rectangle = [(0,0),(0,1),(1,1),(1,0)]
fig, ax = plt.subplots()
ax.add_patch(mpatches.Polygon(rectangle))
automin, automax = plt.xlim()
plt.xlim(automin-0.5, automax+0.5)
automin, automax = plt.ylim()
plt.ylim(automin-0.5, automax+0.5)
plt.show()
Upvotes: 3