Я хочу добавить цветовую карту, чтобы показать градиент по оси x, но, к сожалению, вся фигура становится черной. Мне может чего-то не хватать, помогите мне в этом. Вот код.
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.cm as cm
import numpy as np
# Create a 3D figure
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# Define the vertices of the rectangular rod
vertices = np.array([
[0, -0.5, -0.5],
[0, -0.5, 0.5],
[0, 0.5, 0.5],
[0, 0.5, -0.5],
[10, -0.5, -0.5],
[10, -0.5, 0.5],
[10, 0.5, 0.5],
[10, 0.5, -0.5]
])
# Define the faces of the rectangular rod
faces = np.array([
[0, 1, 2, 3],
[4, 5, 6, 7],
[0, 1, 5, 4],
[1, 2, 6, 5],
[2, 3, 7, 6],
[3, 0, 4, 7]
])
# Map the x-coordinate of each vertex to a color in the colormap
x = vertices[:, 0]
norm = plt.Normalize(x.min(), x.max())
colors = cm.gnuplot(norm(x))
# Create a Poly3DCollection object with the vertices, faces, and colors
rect = Poly3DCollection(vertices[faces], alpha=0.8, facecolors=colors, edgecolors='black')
# Add the rectangular rod to the plot
ax.add_collection3d(rect)
# Set the limits of the x, y, and z axes
ax.set_xlim([0, 10])
ax.set_ylim([-1, 1])
ax.set_zlim([-1, 1])
# Add labels to the axes
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
# Show the plot
plt.show()
Я использовал метод цветовой карты огнестрельного оружия, чтобы придать градиентный цвет 3D-графику, но ничего не работает. Пожалуйста, предложите мне, как действовать. Если есть какой-либо другой метод, с помощью которого я могу создать градиент с 6 цветами, это тоже будет хорошо.
Первая проблема здесь заключается в том, что количество записей в аргументе facecolors
должно совпадать с количеством граней, иначе похоже, что matplotlib возвращается к выбору первого цвета в списке — здесь это черный.
Вторая проблема заключается в том, что вы пытаетесь создать прямоугольный параллелепипед всего с 6 гранями, а затем раскрасить его с помощью гладкой карты цветов. Многоугольники в matplotlib могут быть окрашены только одним цветом каждый. Итак, вы должны разделить свой кубоид.
Вот моя попытка решить эти две проблемы! Я создаю набор точек от 0 до 10, а затем создаю вершины в этих x-позициях. Я также строю массив x-позиций непосредственно из граней, взяв среднее значение x-позиции каждой из четырех вершин, составляющих каждую грань.
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
# Create a 3D figure
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# Define the vertices of the rectangular rod
N_sub = 50 # Set higher for better resolution; lower for better performance!
vertices = np.concatenate([
np.array([[x, -0.5, -0.5],
[x, -0.5, 0.5],
[x, 0.5, 0.5],
[x, 0.5, -0.5]])
for x in np.linspace(0, 10, N_sub + 1)], axis=0)
# Define the faces of the rectangular rod
offset = (N_sub) * 4
faces = np.concatenate([
[[0, 1, 2, 3]],
*[np.array([[3, 0, 4, 7],
[0, 1, 5, 4],
[1, 2, 6, 5],
[2, 3, 7, 6]]) + 4 * x for x in range(0, N_sub)],
[[0 + offset, 1 + offset, 2 + offset, 3 + offset]]
], axis=0)
# Map the x-coordinate of each face to a color in the colormap
x = np.array([np.mean([vertices[idx, 0] for idx in face]) for face in faces])
norm = plt.Normalize(x.min(), x.max())
cmap = plt.get_cmap("gnuplot")
colors = cmap(norm(x))
# Create a Poly3DCollection object with the vertices, faces, and colors
rect = Poly3DCollection(vertices[faces], alpha=0.8, facecolors=colors)
# Add the rectangular rod to the plot
ax.add_collection3d(rect)
# Set the limits of the x, y, and z axes
ax.set_xlim([0, 10])
ax.set_ylim([-1, 1])
ax.set_zlim([-1, 1])
# Add labels to the axes
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
# Show the plot
plt.show()
Надеюсь это поможет! Однако я не уверен, что смогу воспроизвести черные края. Я попытался сделать второй прямоугольный параллелепипед, как ваш оригинальный, с шестью гранями и facecolor = "none"
, но это выдало ошибку.
PS: я сохранил вам импорт с помощью plt.get_cmap
.
Замечательно!. Это решило задачу. Большое спасибо. Но есть небольшое сомнение, когда я пытаюсь расширить тот же график до большего значения, скажем, x = 1000, сохраняя все остальные параметры одинаковыми. График сжимается в направлении x, но я хочу, чтобы он расширялся вдоль x, чтобы я мог привязать к нему горизонтальную полосу прокрутки. Так как мне нужно добавить еще несколько графиков на поверхность вдоль направления x. Поэтому его не будет видно, если он уменьшится. Прошу подсказать, как этого добиться. Я пробовал
set_box_aspect
метод, но он у меня не работает. Я также пытался настроить размер инжира, но ничего не работает.