3D-график Matplotlib: получите единую карту цветов на двух поверхностях

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

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

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

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

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 поверхности с независимой цветовой картой


person laolux    schedule 28.02.2019    source источник


Ответы (1)


Вы можете явно установить 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()

введите здесь описание изображения

Чтобы сделать диапазон близким к фактическим значениям 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()

введите здесь описание изображения

person darksky    schedule 28.02.2019
comment
Большое спасибо, отлично работает для меня! Я предпочитаю ваш первый ответ, он охватывает случай, когда обе поверхности неравны и, следовательно, должны получить неравный объем пространства цветовой карты. - person laolux; 28.02.2019