Как обновить facecolors в объекте mplot3d? - PullRequest
0 голосов
/ 11 февраля 2019

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

В качестве основного примера я попытался создать плоскость, в которой лицевые цвета обеспечиваются функцией евклидоварасстояние до данного центра.Центр - это параметр, который я смогу настроить с помощью ползунков.Вот мой код:

from numpy import pi, sin
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm, colors
from matplotlib.widgets import Slider, Button, RadioButtons

def signal(amp, freq):
    return amp * sin(2 * pi * freq * t)

axis_color = 'lightgoldenrodyellow'

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

# Adjust the subplots region to leave some space for the sliders and buttons
fig.subplots_adjust(bottom=0.25)

x = np.linspace(0.0, 1.0, num=50)
y = np.linspace(0.0, 1.0, num=50)
t = np.linspace(0.0, 1.0, num=50)
x, y = np.meshgrid(x, y)
z = 1.0 * x + 2.0 * y
def colormapping_values(x_center, y_center):
    return (x-x_center)**2 + (y-y_center)**2

x0 = 0.5
y0 = 0.5
norm = colors.Normalize()
somtethin = cm.jet(norm(colormapping_values(x0, y0)))
surf = ax.plot_surface(x, y, z, facecolors=somtethin)
# Draw the initial plot
# The 'line' variable is used for modifying the line later

# Add two sliders for tweaking the parameters

# Define an axes area and draw a slider in it
x_center_slider_pos  = fig.add_axes([0.15, 0.15, 0.65, 0.03], facecolor=axis_color)
x_center_slider = Slider(x_center_slider_pos, 'X center', 0.0, 1.0, valinit=x0)

# Draw another slider
y_center_slider_pos = fig.add_axes([0.15, 0.1, 0.65, 0.03], facecolor=axis_color)
y_center_slider = Slider(y_center_slider_pos, 'Y center', 0.0, 1.0, valinit=y0)
# Define an action for modifying the line when any slider's value changes
def sliders_on_changed(val):
    print(cm.jet(colormapping_values(x_center_slider.val, y_center_slider.val)).shape)
    surf.set_facecolors(cm.jet(colormapping_values(x_center_slider.val, y_center_slider.val)))
    fig.canvas.draw_idle()
x_center_slider.on_changed(sliders_on_changed)
y_center_slider.on_changed(sliders_on_changed)

# Add a button for resetting the parameters
reset_button_ax = fig.add_axes([0.8, 0.025, 0.1, 0.04])
reset_button = Button(reset_button_ax, 'Reset', color=axis_color, hovercolor='0.975')
def reset_button_on_clicked(mouse_event):
    y_center_slider.reset()
    x_center_slider.reset()
reset_button.on_clicked(reset_button_on_clicked)

plt.show()

Исходный график верен, однако, когда я нажимаю ползунок, я получаю «ValueError: Неверный аргумент RGBA» в строке «surf.set_facecolors (cm.jet (colormapping_values ​​(x_center_slider.val, y_center_slider.val))) ".Я полагаю, что я делаю что-то не так при использовании этой функции.Я провел свое исследование, но еще не пришел к выводу о том, что я делаю неправильно, поскольку использование практически идентично тому, что я делаю, когда передаю параметр facecolors

1 Ответ

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

Вам нужно присвоить 1D массив или список цветов .set_facecolors(), а не двумерному массиву, который вы в данный момент задаете.

Для этого измените массив таким образом, чтобы он имел форму ((len(x)-1 * len(y)-1), 4).(обратите внимание, что 4 предназначено для 4-канального значения цвета).

c_len = (len(x)-1 * len(y)-1)

def sliders_on_changed(val):
    print(cm.jet(colormapping_values(x_center_slider.val, y_center_slider.val)).shape)
    surf.set_facecolors(
            cm.jet(colormapping_values(x_center_slider.val, y_center_slider.val)
                )[:-1, :-1].reshape(c_len, 4))
    surf.set_edgecolors(
            cm.jet(colormapping_values(x_center_slider.val, y_center_slider.val)
                )[:-1, :-1].reshape(c_len, 4))    
    fig.canvas.draw_idle()

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

Тестирование с некоторымиразличные значения ползунка:

enter image description here enter image description here enter image description here

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