Home > Mobile >  Fill polygon with vertical gradient in matplotlib?
Fill polygon with vertical gradient in matplotlib?

Time:05-07

I would like to fill in polygons with vertical gradient (white-to-red) using the .set_facecolor() method. I defined a colormap using matplotlib.colors.LinearSegmentedColormap but it seems I am not allowed to pass colormap directly to color setting methods like .set_facecolor(). If I merely pass one color, it runs successfully - how can I pass a gradient to have the intended behavior, with colors ranging from white bottom to red top?

Working snippet, with fix color:

import matplotlib.pyplot as plt
from matplotlib.collections import PatchCollection
from matplotlib.patches import Polygon
from  matplotlib import colors, patches
import numpy as np

fig,ax = plt.subplots(1)

patches = []

verts = np.random.rand(3,2)
polygon = Polygon(verts,closed=True)
patches.append(polygon)

collection = PatchCollection(patches)

ax.add_collection(collection)

collection.set_color("blue")

ax.autoscale_view()
plt.show()

Not working snippet with custom gradient:

cmap = colors.LinearSegmentedColormap.from_list('white_to_red', ['white', 'red'])

fig,ax = plt.subplots(1)

patches = []

verts = np.random.rand(3,2)
polygon = Polygon(verts,closed=True)
patches.append(polygon)

collection = PatchCollection(patches)

ax.add_collection(collection)

collection.set_facecolor(cmap)

ax.autoscale_view()
plt.show()

CodePudding user response:

You can use:

  1. ax.imshow to create an image with a gradient, localized to a specific region of the plot.
  2. the set_clip_path method to mask the polygon-region over the image.

Like this:

import matplotlib.pyplot as plt
from matplotlib.collections import PatchCollection
from matplotlib.patches import Polygon
from  matplotlib import colors, patches
import matplotlib.cm as cm
import numpy as np

fig,ax = plt.subplots(1)

verts = np.random.rand(3, 2)
xmin, xmax = verts[:, 0].min(), verts[:, 0].max()
ymin, ymax = verts[:, 1].min(), verts[:, 1].max()

cmap = colors.LinearSegmentedColormap.from_list('white_to_red', ['white', 'red'])
grad = np.atleast_2d(np.linspace(0, 1, 256)).T
img = ax.imshow(np.flip(grad), extent=[xmin, xmax, ymin, ymax],interpolation='nearest', aspect='auto', cmap=cmap)
polygon = Polygon(verts, closed=True, facecolor='none', edgecolor='none')
ax.add_patch(polygon)
img.set_clip_path(polygon)

ax.autoscale_view()
plt.show()

enter image description here

  • Related