Эта цифра, в комплекте с colorbar
,
введите описание изображения здесь
было создано с помощью следующего скрипта - функция map_colors
, определенная в конце скрипта, могла бы заинтересовать обычного читателя.
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
from itertools import product as Π
# the distribution that we want to study
dirichlet = stats.dirichlet([1.1, 1.5, 1.3])
# generate the "mesh"
N = 30 # no. of triangles along an edge
s = np.linspace(0, 1, N+1)
x, y, z = np.array([(x,y,1-x-y) for x,y in Π(s,s) if x+y<1+1E-6]).T
# plot as usual
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1, projection='3d', azim=20)
p3dc = ax.plot_trisurf(x, y, z)
########## change the face colors ####################
mappable = map_colors(p3dc, dirichlet.pdf, 'Spectral')
# ####################################################
# possibly add a colormap
plt.colorbar(mappable, shrink=0.67, aspect=16.7)
# we are done
plt.show()
def map_colors(p3dc, func, cmap='viridis'):
"""
Color a tri-mesh according to a function evaluated in each barycentre.
p3dc: a Poly3DCollection, as returned e.g. by ax.plot_trisurf
func: a single-valued function of 3 arrays: x, y, z
cmap: a colormap NAME, as a string
Returns a ScalarMappable that can be used to instantiate a colorbar.
"""
from matplotlib.cm import ScalarMappable, get_cmap
from matplotlib.colors import Normalize
from numpy import array
# reconstruct the triangles from internal data
x, y, z, _ = p3dc._vec
slices = p3dc._segslices
triangles = array([array((x[s],y[s],z[s])).T for s in slices])
# compute the barycentres for each triangle
xb, yb, zb = triangles.mean(axis=1).T
# compute the function in the barycentres
values = func(xb, yb, zb)
# usual stuff
norm = Normalize()
colors = get_cmap(cmap)(norm(values))
# set the face colors of the Poly3DCollection
p3dc.set_fc(colors)
# if the caller wants a colorbar, they need this
return ScalarMappable(cmap=cmap, norm=norm)