Как построить плоскость, не затрагивая масштаб основного сюжета? - PullRequest
2 голосов
/ 05 января 2020

Я пытаюсь нанести плоскость на график без масштабирования или перезаписи основного графика. В идеале я хочу помочь визуализации потенциального барьера в сложной визуализации волновой функции, это может быть сделано путем создания затененного объема между областью потенциала ... Я думал, что мог бы сделать две плоскости для этой цели но они замышляются, скрывая мой основной сюжет. Это две фотографии моих полученных графиков без и с плоскостями, которые я пробовал соответственно:

Picture without the planes

Picture of the planes

Я думаю, что, возможно, перезаписываю основной сюжет, но не могу найти четкого решения этой проблемы, это код, который я использую для создания сюжета и анимации (При необходимости я могу поделиться всем кодом ):

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.animation as animation
import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.gca(projection='3d')
ax.get_proj = lambda: np.dot(Axes3D.get_proj(ax), np.diag([1.5, 0.7, 0.7, 1]))

line,=ax.plot(x,IMAG[0,:],REAL[0,:],"r",linewidth=0.5)

ax.set_xlabel('Posició (nm)')
ax.set_ylabel('$Im[\psi(x,t)]$')
ax.set_zlabel('$Re[\psi(x,t)]$')

#Here are the two planes
yy, zz = np.meshgrid(range(-2,2), range(-2,2))

ax2 = plt.subplot(projection='3d')
ax2.plot_surface(-l, yy, zz,color='b',alpha=0.2)
ax2.plot_surface(l, yy, zz,color='b',alpha=0.2)

def animacio(i):
    ax.collections.clear()
    line.set_data(REAL[i,:],IMAG[i,:])
    line.set_3d_properties(x, 'x')


    return line,
ani=animation.FuncAnimation(fig,animacio,interval=50, frames=Nt,repeat=True)
ani.save(f'Evolució_[{V0},{L},{l},{xi},{sigmax},{T}].mp4', writer="ffmpeg", dpi=300)
plt.show()

1 Ответ

2 голосов
/ 05 января 2020

Вы строите плоскости на отдельном участке от волновой функции. Вместо

ax2 = plt.subplot(projection='3d')
ax2.plot_surface(-l, yy, zz,color='b',alpha=0.2)
ax2.plot_surface(l, yy, zz,color='b',alpha=0.2)

Попробуйте

ax.plot_surface(-l, yy, zz, color='b', alpha=0.2)
ax.plot_surface(l, yy, zz, color='b', alpha=0.2)

И вы должны увидеть плоскости на том же графике, что и волновая функция. Вам также может понадобиться удалить

ax.collections.clear()

из функции анимации, используя set_data и set_3d_properties , если достаточно для анимации волновой функции без изменения плоскостей.


Редактировать

Чтобы изображение не влияло на масштаб графика, вы можете заранее установить пределы графика, например

ax.set_xlim([-20, 20])
ax.set_ylim([-0.6, 0.6])
ax.set_zlim([-0.6, 0.6])

Примечание. однако, что полная протяженность плоскостей будет построена независимо от этого - необходимо правильно выполнить создание, чтобы учесть это. Следующие действия должны сделать это

yy, zz = np.meshgrid(np.linspace(-1,1), np.linspace(-1,1))

Я сталкивался с проблемами с использованием set_data и set_3d_properties в прошлом, если они не работают, вы должны просто очистить ось и заново построить волновую функцию и ограничивающие плоскости. наряду со сбросом ограничений на каждую итерацию.

Ниже приведен полный пример, иллюстрирующий вышеприведенное

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

n = 200
fig = plt.figure(figsize=(16,6))
ax = fig.add_subplot(111, projection='3d')
yy, zz = np.meshgrid(np.linspace(-1,1), np.linspace(-1,1))

def update(i):
    # Show propagation of demonstration wavefunction in +x direction
    i *= 22
    p = np.zeros((3, n*4))
    p[0,:] = np.linspace(-np.pi*16, np.pi*16, n*4)
    x = p[0,i:i+n*2]
    p[1,i:i+n*2] = np.sin(2*x + np.pi/2) * np.sin(x/16 + np.pi/2)/2
    p[2,i:i+n*2] = np.sin(2*x) * np.cos(x/16)/2
    # Plotting
    plt.cla()
    ax.set_xlim([-np.pi*16, np.pi*16])
    ax.set_ylim([-1,1])
    ax.set_zlim([-1,1])
    ax.plot_surface(np.full_like(yy, -np.pi*16), yy, zz, color='b', alpha=0.2)
    ax.plot_surface(np.full_like(yy, np.pi*16), yy, zz, color='b', alpha=0.2)
    plot, = ax.plot(p[0,:], p[1,:], p[2,:], color='red', lw=1)
    return plot,

anim = animation.FuncAnimation(fig, update, frames=n//10, interval=2000/(n//10))
anim.save('wavefunc.gif', writer='imagemagick')

enter image description here

...