简体   繁体   English

3d plot 中 Z1587383CF8EF7F7FBDD06 中 2d 切片 function 下方的填充区域

[英]Filling area below function on 3d plot of 2d slices in Matplotlib

I would like to make a 3D plot with several 2D line plot "slices" and shade the area between the x-axis and the curve (ie under the curve).我想用几条二维线 plot “切片”制作 3D plot “切片”并遮蔽 x 轴和曲线之间的区域(即曲线下)。 When trying to do this with polygons I am getting filling but the correct areas are not being filled.尝试使用多边形执行此操作时,我正在填充,但未填充正确的区域。 Any help would be most appreciated!非常感激任何的帮助!

%matplotlib notebook

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import PolyCollection
from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure(figsize=(15,15))
ax = fig.add_subplot(111, projection='3d')

colors = ['r','b','g','m']
phi = [0,np.pi/4,np.pi/3, np.pi/2]

for c, k in zip(colors, phi):
    
    eps2 = 0.001j
    eps = np.linspace(-3,3,10000)
    E = eps + eps2
  
    gR = ((1-(((np.cos(k)+np.sin(k)*1j)**2)/((E+np.sqrt(1-E**2)*1j)**4)))/(1+(((np.cos(k)+np.sin(k)*1j)**2)/((E+np.sqrt(1-E**2)*1j)**4))))*1j
    N = gR.imag
    utol = 2
    N[N>utol] = 2   

    ax.plot(eps, N, k,zdir='y', color=c)
    
    verts = [list(zip(eps,N))]
    poly = PolyCollection(verts, facecolors=c)
    poly.set_alpha(1)
    ax.add_collection3d(poly, zs=k,zdir='y')
        
ax.set_xlabel('Energy')
ax.set_ylabel('Phi')
ax.set_zlabel('DOS')

ax.set_yticks(phi)
ax.set_zlim(0,2)
ax.set_ylim(0,2)

plt.show()

Incorrect Plot for reference:不正确的 Plot 供参考:

不正确的绘图供参考

You created a polygon by connecting the first and last vertex of your curves.您通过连接曲线的第一个和最后一个顶点创建了一个多边形。 As these vertices have y = 2 everything gets connected with the horizontal line at that y-value.由于这些顶点的y = 2 ,因此所有内容都与该 y 值处的水平线相连。 To close the polygon at zero, repeat the first and the last x-value ( np.pad(eps, 1, mode='edge') ) and pad the y-values with a zero at both ends ( np.pad(N, 1) ).要将多边形闭合为零,请重复第一个和最后一个 x 值( np.pad(eps, 1, mode='edge') )并在两端用零填充 y 值( np.pad(N, 1) )。

If desired, ax.set_yticklabels(...) can show the y-ticks as a formula with pi.如果需要, ax.set_yticklabels(...)可以将 y 刻度显示为带有 pi 的公式。

Further, matplotlib seems to have a serious problem about deciding the relative depth of each polygon, showing them all mixed up.此外,matplotlib 在确定每个多边形的相对深度方面似乎存在严重问题,将它们全部混合在一起。 A workaround could be to rotate everything 180 degrees, eg by setting ax.view_init(elev=22, azim=130) .一种解决方法可能是将所有内容旋转 180 度,例如通过设置ax.view_init(elev=22, azim=130)

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import PolyCollection
from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure(figsize=(15, 15))
ax = fig.add_subplot(111, projection='3d')

colors = ['r', 'b', 'g', 'm']
phi = [0, np.pi / 4, np.pi / 3, np.pi / 2]

for c, k in zip(colors, phi):
    eps2 = 0.001j
    eps = np.linspace(-3, 3, 10000)
    E = eps + eps2

    gR = ((1 - (((np.cos(k) + np.sin(k) * 1j) ** 2) / ((E + np.sqrt(1 - E ** 2) * 1j) ** 4))) / (
            1 + (((np.cos(k) + np.sin(k) * 1j) ** 2) / ((E + np.sqrt(1 - E ** 2) * 1j) ** 4)))) * 1j
    N = gR.imag
    utol = 2
    N[N > utol] = 2

    ax.plot(eps, N, k, zdir='y', color=c)

    verts = [list(zip(np.pad(eps, 1, mode='edge'), np.pad(N, 1)))]
    poly = PolyCollection(verts, facecolors=c)
    poly.set_alpha(1)
    ax.add_collection3d(poly, zs=k, zdir='y')

ax.set_xlabel('Energy')
ax.set_ylabel('Phi')
ax.set_zlabel('DOS')

ax.set_yticks(phi)
ax.set_yticklabels(['$0$' if k == 0 else f'$\pi / {np.pi / k:.0f}$' for k in phi])
ax.set_zlim(0, 2)
ax.set_ylim(0, 2)
ax.view_init(elev=22, azim=130)
plt.show()

结果图

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM