Matplotlib: установите cmap в plot_surface для осей X и Y - PullRequest
0 голосов
/ 30 октября 2018

Как мне установить цветовую карту относительно радиуса фигуры?

А как мне закрыть концы цилиндра (сбоку, а не сверху и снизу)?

Мой сценарий:

import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from math import sin, cos, pi

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

h, w = 60,30
znew = np.random.randint(low=90, high=110, size=(60,30))
theta = np.linspace(0,2*pi, h)
Z = np.linspace(0,1,w)

Z,theta = np.meshgrid(Z, theta)

R = 1
X = (R*np.cos(theta))*znew
Y = (R*np.sin(theta))*znew


ax1 = ax.plot_surface(X,Y,Z,linewidth = 0, cmap="coolwarm",              
vmin= 80,vmax=130, shade = True, alpha = 0.75)

fig.colorbar(ax1, shrink=0.9, aspect=5)

plt.show()

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

1 Ответ

0 голосов
/ 31 октября 2018

Сначала вам нужно использовать аргумент ключевого слова facecolors, равный plot_surface, чтобы нарисовать поверхность произвольными (не Z) цветами. Вы должны передать явный цвет RGBA четыре в каждой точке, что означает, что нам нужно выбрать объект карты цветов с ключами, заданными радиусом в каждой точке. Наконец, это нарушит свойство mappable полученной поверхности, поэтому нам нужно будет создать цветную полосу, вручную указав ей использовать наши радиусы для цветов:

import numpy as np
from matplotlib import pyplot as plt
import matplotlib.cm as cm
from matplotlib.colors import Normalize
from mpl_toolkits.mplot3d import Axes3D

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

h, w = 60,30
#znew = np.random.randint(low=90, high=110, size=(h,w))
theta = np.linspace(0,2*np.pi, h)
Z = np.linspace(0,1,w)

Z,theta = np.meshgrid(Z, theta)
znew = 100 + 10*np.cos(theta/2)*np.cos(2*Z*np.pi)

R = 1
X = (R*np.cos(theta))*znew
Y = (R*np.sin(theta))*znew
true_radius = np.sqrt(X**2 + Y**2)
norm = Normalize()
colors = norm(true_radius) # auto-adjust true radius into [0,1] for color mapping

cmap = cm.get_cmap("coolwarm")
ax.plot_surface(X, Y, Z, linewidth=0, facecolors=cmap(colors), shade=True, alpha=0.75)

# the surface is not mappable, we need to handle the colorbar manually
mappable = cm.ScalarMappable(cmap=cmap)
mappable.set_array(colors)
fig.colorbar(mappable, shrink=0.9, aspect=5)

plt.show()

Обратите внимание, что я изменил радиусы на что-то плавное для менее хаотично выглядящего результата. Аргумент true_radius содержит действительные радиусы в единицах данных, которые после нормализации становятся colors (по существу colors = (true_radius - true_radius.min())/true_radius.ptp()).

Результат:

pretty result with colours as expected

Наконец, обратите внимание, что я создал радиусы так, чтобы цилиндр не закрывался незаметно. Это имитирует ваш случайный пример ввода. ничего вы не можете с этим поделать, если радиусы не являются 2π-периодическими в theta. Это не имеет ничего общего с визуализацией, это геометрия.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...