I have a list of 10,000+ Matplotlib Polygon objects. Each polygon belongs to 1 of 20 groups. I want to differentiate which group a polygon belongs to by mapping each unique group to a unique color.
Here are some posts I've found with similar issues to mine:
Fill polygons with multiple colors in python matplotlib
How to fill polygons with colors based on a variable in Matplotlib?
How do I set color to Rectangle in Matplotlib?
These solutions simply apply a random color to each shape in the list. That is not what I am looking for. For me, each shape belonging to a particular group should have the same color. Any ideas?
Sample code:
from matplotlib.collections import PatchCollection
from matplotlib.patches import Polygon
from matplotlib import pyplot as plt
patches = []
colors = []
num_polys = 10000
for i in range(num_polys):
patches.append(Polygon(poly_vertices[i], closed=True))
colors.append(poly_colors[i]) # This line is pointless, but I'm letting you know that
# I have a particular color for each polygon
fig, ax = plt.subplots()
p = PatchCollection(patches, alpha=0.25)
ax.add_collection(p)
ax.autoscale()
plt.show()
Note that if you run this code, it won't work because poly_vertices and poly_colors haven't been defined. For now, just assume that poly_vertices is a list of polygon vertices, and poly_colors is a list of RGB colors and each list has 10000 entries.
For example: poly_vertices[0] = [(0, 0), (1, 0), (0, 1)], colors[0] = [1, 0, 0]
Thank you!
Okay, I figured out what I was trying to do. I'll post the answer for anyone who may be having similar issues.
For some reason, setting the color in the polygon itself doesn't work. i.e.
Polygon(vertices, color=[1, 0, 0])
does not work.
Instead, after adding all the polygons to a collection, use
p = PatchCollection(patches)
p.set_color([1, 0, 0])
But I still want to group polygons by color. Therefore I need to add multiple PatchCollections -- one for each group type!
My original list of polygons were in no particular order, so the first polygon may belong to group 5, while its neighbor belongs to group 1, etc.
So, I first sorted the list by group number such that all polygons belonging to a particular group were right next to each other.
I then iterated through the sorted list and appended each polygon to a temporary list. Upon reaching a new group type, I knew it was time to add all the polygons in the temporary list to their own PatchCollection.
Here's some code for this logic:
a = [x for x in original_groups] # The original group numbers (unsorted)
idx = sorted(range(len(a)), key=lambda k: a[k]) # Get indices of sorted group numbers
current_group = original_groups[idx[0]] # Set the current group to the be the first sorted group number
temp_patches = [] # Create a temporary patch list
for i in idx: # iterate through the sorted indices
if current_group == original_groups[i]: # Detect whether a change in group number has occured
temp_patches.append(original_patches[i]) # Add patch to the temporary variable since group number didn't change
else:
p = PatchCollection(temp_patches, alpha=0.6) # Add all patches belonging to the current group number to a PatchCollection
p.set_color([random.uniform(0, 1), random.uniform(0, 1), random.uniform(0, 1)]) # Set all shapes belonging to this group to the same random color
ax.add_collection(p) # Add all shapes belonging this group to the axes object
current_group = original_groups[i] # The group number has changed, so update the current group number
temp_patches = [original_patches[i]] # Reset temp_patches, to begin collecting patches of the next group number
p = PatchCollection(temp_patches, alpha=0.6) # temp_patches currently contains the patches belonging to the last group. Add them to a PatchCollection
p.set_color([random.uniform(0, 1), random.uniform(0, 1), random.uniform(0, 1)])
ax.add_collection(p)
ax.autoscale() # Default scale may not capture the appropriate region
plt.show()
By turning on the match_original option, you can set the color of polygons individually (e.g. Polygon(vertices, color=[1, 0, 0])
)
PatchCollection(patches, match_original=True)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With