Max*_*ers 3 python matplotlib triangulation
我基本上想在其支持上“imshow”三维狄利克雷分布的pdf。下面的函数simplex计算该支撑上的常规点,这些点存储在数组 中sim。该数组pdf保存 中每一行的标量密度sim。
我首先想到的是使用三角测量。然而,color的参数plot_trisurface仅支持所有三角形使用一种颜色。根据 z 坐标值设置cmap三角形的颜色(见图 1)。也plot_trisurface忽略了facecolorskwarg。然而,我想要的是基于 为表面着色pdf。
作为一种解决方法,我发现可以将表面插值为 3d 散点图。这通常会给出所需的可视化效果,但我清楚地看到它是一个散点图;特别是在边界上。(见图 2。)
有没有办法将 pdf 的投影绘制到单纯形上?
import itertools
import matplotlib.pyplot as plt
import numpy as np
from scipy import stats
def simplex(n_vals):
base = np.linspace(0, 1, n_vals, endpoint=False)
coords = np.asarray(list(itertools.product(base, repeat=3)))
return coords[np.isclose(coords.sum(axis=-1), 1.0)]
sim = simplex(20)
pdf = stats.dirichlet([1.1, 1.5, 1.3]).pdf(sim.T)
fig1 = plt.figure()
ax1 = fig1.add_subplot(1, 2, 1, projection='3d', azim=20)
ax2 = fig1.add_subplot(1, 2, 2, projection='3d', azim=20)
ax1.plot_trisurf(x, y, z, color='k')
ax2.plot_trisurf(x, y, z, cmap='Spectral')
fig2 = plt.figure()
ax21 = fig2.add_subplot(projection='3d', azim=20)
ax21.scatter3D(*sim.T, s=50, alpha=.5, c=pdf, cmap='Spectral')
Run Code Online (Sandbox Code Playgroud)
该图包含一个colorbar,
由以下脚本 \xe2\x80\x94 生成map_colors,在脚本末尾定义的函数可能会引起一般读者的兴趣。
import numpy as np\nimport matplotlib.pyplot as plt\nfrom scipy import stats\nfrom itertools import product as \xce\xa0\n\n# the distribution that we want to study\ndirichlet = stats.dirichlet([1.1, 1.5, 1.3])\n\n# generate the "mesh"\nN = 30 # no. of triangles along an edge\ns = np.linspace(0, 1, N+1)\nx, y, z = np.array([(x,y,1-x-y) for x,y in \xce\xa0(s,s) if x+y<1+1E-6]).T\n\n# plot as usual\nfig = plt.figure() \nax = fig.add_subplot(1, 1, 1, projection=\'3d\', azim=20) \np3dc = ax.plot_trisurf(x, y, z)\n\n########## change the face colors ####################\nmappable = map_colors(p3dc, dirichlet.pdf, \'Spectral\')\n# ####################################################\n\n# possibly add a colormap\nplt.colorbar(mappable, shrink=0.67, aspect=16.7)\n\n# we are done\nplt.show()\n\ndef map_colors(p3dc, func, cmap=\'viridis\'):\n """\nColor a tri-mesh according to a function evaluated in each barycentre.\n\n p3dc: a Poly3DCollection, as returned e.g. by ax.plot_trisurf\n func: a single-valued function of 3 arrays: x, y, z\n cmap: a colormap NAME, as a string\n\n Returns a ScalarMappable that can be used to instantiate a colorbar.\n """\n \n from matplotlib.cm import ScalarMappable, get_cmap\n from matplotlib.colors import Normalize\n from numpy import array\n\n # reconstruct the triangles from internal data\n x, y, z, _ = p3dc._vec\n slices = p3dc._segslices\n triangles = array([array((x[s],y[s],z[s])).T for s in slices])\n\n # compute the barycentres for each triangle\n xb, yb, zb = triangles.mean(axis=1).T\n \n # compute the function in the barycentres\n values = func(xb, yb, zb)\n\n # usual stuff\n norm = Normalize()\n colors = get_cmap(cmap)(norm(values))\n\n # set the face colors of the Poly3DCollection\n p3dc.set_fc(colors)\n\n # if the caller wants a colorbar, they need this\n return ScalarMappable(cmap=cmap, norm=norm)\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
2830 次 |
| 最近记录: |