Сюжет Matplotlib 3d: получить единую цветовую карту на 2 поверхностях - PullRequest
0 голосов
/ 28 февраля 2019

Я делаю 3D-график с помощью matplotlib с 2 поверхностями (см. Пример ниже).До сих пор обе поверхности получают свою собственную цветовую карту: синий внизу и желтый сверху.

Однако я хочу по одной цветовой карте для обеих поверхностей, то есть самое нижнее синее, самое верхнее желтое иточка соприкосновения обеих поверхностей - зеленая.

Как этого добиться?Нужно ли каким-либо образом комбинировать обе поверхности перед нанесением или нужно ограничить цветовые карты обеих поверхностей (от синего до зеленого, от зеленого до желтого)?

Спасибо за помощь.

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d
from matplotlib import cm

ky = np.linspace(-np.pi*2/3,np.pi*2/3,100)
kz = np.linspace(-np.pi*2/3,np.pi*2/3,100)

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

KY, KZ = np.meshgrid(ky, kz)
E = np.cos(KY)*np.cos(KZ)
ax.plot_surface(KY, KZ, E-1, rstride=1, cstride=1, cmap=cm.viridis)   #surface 1
ax.plot_surface(KY, KZ, -E+1, rstride=1, cstride=1, cmap=cm.viridis)  #surface 2
ax.view_init(elev=7, azim=-69)
plt.show()

2 surfaces with independent colormap

1 Ответ

0 голосов
/ 28 февраля 2019

Вы можете явно установить vmin и vmax для цветовой карты, чтобы задать диапазон для цветов.

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d
from matplotlib import cm

ky = np.linspace(-np.pi*2/3,np.pi*2/3,100)
kz = np.linspace(-np.pi*2/3,np.pi*2/3,100)

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

KY, KZ = np.meshgrid(ky, kz)
E = np.cos(KY)*np.cos(KZ)
ax.plot_surface(KY, KZ, E-1, rstride=1, cstride=1, cmap=cm.viridis, vmin=-2, vmax=2)   #surface 1
ax.plot_surface(KY, KZ, -E+1, rstride=1, cstride=1, cmap=cm.viridis, vmin=-2, vmax=2)  #surface 2
ax.view_init(elev=7, azim=-69)
plt.show()

enter image description here

Длясделав диапазон жестким по отношению к фактическим значениям Z на двух поверхностях, вы можете использовать

vmin=np.amin(E-1), vmax=np.amax(-E+1)

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

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d
from matplotlib import cm
from matplotlib.colors import ListedColormap

ky = np.linspace(-np.pi*2/3,np.pi*2/3,100)
kz = np.linspace(-np.pi*2/3,np.pi*2/3,100)

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

KY, KZ = np.meshgrid(ky, kz)
E = np.cos(KY)*np.cos(KZ)

viridis = cm.get_cmap('viridis', 512)
topcolors = viridis(np.linspace(0.5, 1, 256))
topcm = ListedColormap(topcolors)
bottomcolors = viridis(np.linspace(0, 0.5, 256))
bottomcm = ListedColormap(bottomcolors)

ax.plot_surface(KY, KZ, E-1, rstride=1, cstride=1, cmap=bottomcm)   #surface 1
ax.plot_surface(KY, KZ, -E+1, rstride=1, cstride=1, cmap=topcm)  #surface 2
ax.view_init(elev=7, azim=-69)
plt.show()

enter image description here

...