Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filling triangles in Matplotlib triplot with individual colors

Is it possible to plot a list of triangles generated by scipy.spatial.Delaunay using pyplot's triplot function so that each triangle can be drawn and filled with an individual color? The basic python script I've created is

import numpy as np
import matplotlib.pyplot as plt
from scipy.spatial import Delaunay
import matplotlib.image as mpimg  

h = 300
w = 1000

npts = 30

pts = np.zeros((npts,2))
pts[:,0] = np.random.randint(0,w,npts)
pts[:,1] = np.random.randint(0,h,npts)
tri = Delaunay(pts)

plt.xlim(0, w)
plt.ylim(0, h)

# Determine the color used for each triangle based upon the orthocenter
# of the triangle and the corresponding pixel color in a background image.

centers = np.sum(pts[tri.simplices], axis=1, dtype='int')/3.0
colors = [img[y,x] for x,y in centers]

# This plots the edges of each triangle with no fill. I'd like to 
# include the colors list to plot a fill for each.

plt.triplot(pts[:,0], pts[:,1], tri.simplices.copy())

plt.show()

Is there some argument to triplot where I can pass the colors list which contains the color for the corresponding triangle. I'm sure I can draw each triangle in a loop, using the appropriate fill color, but it be good if there was a more elegant and faster method.

like image 220
sizzzzlerz Avatar asked Jan 10 '23 00:01

sizzzzlerz


1 Answers

The functionality you're looking for is included in pyplot.tripcolor.

From its documentation, you'll see that it is "smart" and tries to guess whether you have specified colors for the points or for the triangles:

The next argument must be C, the array of color values, either one per point in the triangulation if color values are defined at points, or one per triangle in the triangulation if color values are defined at triangles. If there are the same number of points and triangles in the triangulation it is assumed that color values are defined at points; to force the use of color values at triangles use the kwarg facecolors=C instead of just C.

To continue with your example:

import numpy as np
import matplotlib.pyplot as plt
from scipy.spatial import Delaunay

h = 300
w = 1000
npts = 500
pts = np.zeros((npts,2))
pts[:,0] = np.random.randint(0,w,npts)
pts[:,1] = np.random.randint(0,h,npts)
tri = Delaunay(pts)
plt.xlim(0, w)
plt.ylim(0, h)
centers = np.sum(pts[tri.simplices], axis=1, dtype='int')/3.0
colors = np.array([ (x-w/2.)**2 + (y-h/2.)**2 for x,y in centers])
plt.tripcolor(pts[:,0], pts[:,1], tri.simplices.copy(), facecolors=colors, edgecolors='k')
plt.gca().set_aspect('equal')
plt.show()

Here I merely based the color on the distance between the center of the triangle and the center of the image (because I don't have a suitable image).

enter image description here

like image 108
Oliver W. Avatar answered Jan 16 '23 20:01

Oliver W.