USER
Необходимо чтобы каждый поверхность в программе становилась более прозрачной ближе к нижней плоскости
import numpy as np
import matplotlib.pyplot as plt
import scipy.integrate as integrate
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
def graph_view(ax, sigmaI, muI, sigmaV, muV, Imin, Imax, Vmin, Vmax, alpha, colorPart, color, alphaPart):
I, V = np.meshgrid(np.linspace(IlimMin, IlimMax, 150), np.linspace(VlimMin, VlimMax, 150))
F = np.exp((-(I-muI)**2-(np.log(V)-muV)**2)/(2 * sigmaI**2 * sigmaV**2))/(sigmaI * sigmaV * V * 2*np.pi)
# ax.plot_surface(I, V, F)
# Определяем диапазон для выделения цветом (например, z_min < z < z_max)
z_min, z_max = 0.5, 1.0
# Создаем поверхность
surface = ax.plot_surface(I, V, F, alpha=alpha, edgecolor='none', color=color)
# # Нахождение максимума
max_idx = np.unravel_index(np.argmax(F, axis=None), F.shape)
min_idx = np.unravel_index(np.argmin(F, axis=None), F.shape)
# max_I = I[max_idx]
# max_V = V[max_idx]
max_F = F[max_idx]
min_F = F[min_idx]
# # Печатаем координаты максимальной точки для проверки
# print(f"Max I: {max_I}, Max V: {max_V}, Max F: {max_F}")
# # Печатаем координаты максимальной точки для проверки
# print(f"Max I: {max_I}, Max V: {max_V}, Max F: {max_F}")
# # # Построение вертикальной линии
# ax.plot([max_I, max_I], [max_V, max_V], [0, max_F], color="r", linestyle="--")
# # Отметка максимальной точки
# ax.scatter(max_I, max_V, max_F, color="r", s=50)
# # Добавление дополнительных отметок на осях
# ax.text(max_I+0.05, max_V+0.05, max_F, f"P = {max_F:.4f}", color="black")
# ax.text(max_I, 0, 0, f"{max_I:.2f}", color="black")
# ax.text(IlimMax, max_V, 0, f"{max_V:.2f}", color="black")
# # Добавление линий на плоскости
# ax.plot([max_I, max_I], [0, max_V], [0, 0], color="red", linestyle="--")
# ax.plot([IlimMax, max_I], [max_V, max_V], [0, 0], color="red", linestyle="--")
# Определяем маску для выделенного диапазона
mask = (I >= Imin) & (I <= Imax) & (V >= Vmin) & (V <= Vmax)
# Копируем данные, чтобы изменить цвет только выделенной части
x_highlight = np.copy(I)
y_highlight = np.copy(V)
z_highlight = np.copy(F)
# Обнулим значения, которые не входят в диапазон, чтобы они не отображались
x_highlight[~mask] = np.nan
y_highlight[~mask] = np.nan
z_highlight[~mask] = np.nan
# Добавляем выделенную часть на поверхность другим цветом
highlight_surface = ax.plot_surface(x_highlight, y_highlight, z_highlight, color=colorPart, alpha = alphaPart, edgecolor='none')
# # Вычисление среднего значения z (плотности вероятности) для выделенной области
# mean_F = np.nanmean(z_highlight) # Используем np.nanmean для игнорирования np.nan
# # Маска для выделенной области без nan
# masked_I = I[mask]
# masked_V = V[mask]
# masked_F = F[mask]
# # Вычисляем взвешенные средние координаты
# mean_I = np.sum(masked_I * masked_F) / np.sum(masked_F)
# mean_V = np.sum(masked_V * masked_F) / np.sum(masked_F)
# print('mean_I, mean_V, mean_F', mean_I, mean_V, mean_F)
# # Отметка средней точки на выделенной части поверхности
# ax.scatter(mean_I, mean_V, mean_F, color="red", s=50)
# ax.plot([mean_I, mean_I], [mean_V, mean_V], [0, mean_F], color="red", linestyle="--")
# ax.plot([mean_I, mean_I], [0, mean_V], [0, 0], color="red", linestyle="--")
# ax.plot([IlimMax, mean_I], [mean_V, mean_V], [0, 0], color="red", linestyle="--")
# ax.text(mean_I, mean_V, mean_F+0.0005, f"P = {mean_F:.4f}", color="black")
# ax.text(mean_I, 0, 0, f"{mean_I:.2f}", color="black")
# ax.text(IlimMax, mean_V, 0, f"{mean_V:.2f}", color="black")
# Настраиваем отображение и цветовую карту
# fig.colorbar(surface, ax=ax, shrink=0.5, aspect=5)
ax.set_xlabel('Потребляемый ток')
ax.set_ylabel('Скорость')
ax.set_zlabel('Плотность веростности')
# plt.xlim(16.66, 20)
# plt.ylim(0, 0.75)
return surface
def graph_view_without_part(ax, sigmaI, muI, sigmaV, muV, alpha, color):
I, V = np.meshgrid(np.linspace(IlimMin, IlimMax, 150), np.linspace(VlimMin, VlimMax, 150))
# F = np.exp((-(I-muI)**2-(np.log(V)-muV)**2)/(2 * sigmaI**2 * sigmaV**2))/(sigmaI * sigmaV * V * 2*np.pi)
# F = (np.exp(-0.5* ((I-muI)/sigmaI)**2 + ((V-muV)/sigmaV)**2 )) / (sigmaI*sigmaV*2*np.pi)
F1 = np.exp(-0.5*((I-muI)/sigmaI)**2)
F2 = np.exp(-0.5*((V-muV)/sigmaV)**2)
F = F1*F2
# ax.plot_surface(I, V, F)
# Определяем диапазон для выделения цветом (например, z_min < z < z_max)
z_min, z_max = 0.5, 1.0
# Создаем поверхность
surface = ax.plot_surface(I, V, F, alpha=alpha, edgecolor='none', color=color)
# Нахождение максимума
max_idx = np.unravel_index(np.argmax(F, axis=None), F.shape)
max_I = I[max_idx]
max_V = V[max_idx]
max_F = F[max_idx]
# Печатаем координаты максимальной точки для проверки
print(f"Max I: {max_I}, Max V: {max_V}, Max F: {max_F}")
# Печатаем координаты максимальной точки для проверки
print(f"Max I: {max_I}, Max V: {max_V}, Max F: {max_F}")
# # Построение вертикальной линии
# ax.plot([max_I, max_I], [max_V, max_V], [0, max_F], color="r", linestyle="--")
# # Отметка максимальной точки
# ax.scatter(max_I, max_V, max_F, color="r", s=50)
# # Добавление дополнительных отметок на осях
# ax.text(max_I+0.05, max_V+0.05, max_F, f"P = {max_F:.4f}", color="black")
# ax.text(max_I, 0, 0, f"{max_I:.2f}", color="black")
# ax.text(IlimMax, max_V, 0, f"{max_V:.2f}", color="black")
# # Добавление линий на плоскости
# ax.plot([max_I, max_I], [0, max_V], [0, 0], color="red", linestyle="--")
# ax.plot([IlimMax, max_I], [max_V, max_V], [0, 0], color="red", linestyle="--")
ax.set_xlabel('Потребляемый ток')
ax.set_ylabel('Скорость')
ax.set_zlabel('Плотность веростности')
return surface
def background(ax):
zmin = 0
square1 = np.array([[0, 0, zmin], [3.33, 0, zmin], [3.33, 0.75, zmin], [0, 0.75, zmin]])
square2 = np.array([[3.33, 0, zmin], [10, 0, zmin], [10, 0.75, zmin], [3.33, 0.75, zmin]])
square3 = np.array([[10, 0, zmin], [16.66, 0, zmin], [16.66, 0.75, zmin], [10, 0.75, zmin]])
square4 = np.array([[16.66, 0, zmin], [20, 0, zmin], [20, 0.75, zmin], [16.66, 0.75, zmin]])
square5 = np.array([[3.33, 0.75, zmin], [10, 0.75, zmin], [10, 2.25, zmin], [3.33, 2.25, zmin]])
square6 = np.array([[10, 0.75, zmin], [16.66, 0.75, zmin], [16.66, 2.25, zmin], [10, 2.25, zmin]])
square7 = np.array([[16.66, 0.75, zmin], [20, 0.75, zmin], [20, 2.25, zmin], [16.66, 2.25, zmin]])
square8 = np.array([[10, 2.25, zmin], [16.66, 2.25, zmin], [16.66, 3.75, zmin], [10, 3.75, zmin]])
square9 = np.array([[16.66, 2.25, zmin], [20, 2.25, zmin], [20, 3.75, zmin], [16.66, 3.75, zmin]])
square10 = np.array([[10, 3.75, zmin], [16.66, 3.75, zmin], [16.66, 4.5, zmin], [10, 4.5, zmin]])
square11 = np.array([[16.66, 3.75, zmin], [20, 3.75, zmin], [20, 4.5, zmin], [16.66, 4.5, zmin]])
sq = [square1, square2, square3, square4, square5, square6, square7, square8, square9, square10, square11]
colors = ['green', 'gold', 'red', 'firebrick', 'gold', 'gold', 'firebrick', 'gold', 'red', 'red', 'red']
for i in range(len(sq)):
square = Poly3DCollection([sq[i]], color=colors[i], edgecolor='none', alpha = 0.5)
ax.add_collection3d(square)
# ax.plot_surface(square1[0], square1[1], square1[2], color = 'green', alpha = 1)
def integrand(I, V):
return np.exp((-(I-muI)**2-(np.log(V)-muV)**2)/(2 * sigmaI**2 * sigmaV**2))/(sigmaI * sigmaV * V * 2*np.pi)
def square(Imin, Imax, Vmin, Vmax):
result, error = integrate.dblquad(integrand, Imin, Imax, lambda x: Vmin, lambda x: Vmax)
print(f"Result: {result}, Error estimate: {error}")
def calculate_alpha(z_value, F_min, F_max):
min_alpha = 0.2
max_alpha = 1.0
return min_alpha + (max_alpha - min_alpha) * (z_value - F_min) / (F_max - F_min)
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1, projection='3d', computed_zorder = False)
# IlimMin = 16.66
# IlimMax = 20
# VlimMin = 0.001
# VlimMax = 0.75
IlimMin = 0
IlimMax = 20
VlimMin = 0
VlimMax = 4.5
# # для второго приступа
sigmaI = 2.33
muI = 11.46
sigmaV = 0.755
muV = -0.611
Imin, Imax = 17.04, 19.67
Vmin, Vmax = 0.55, 0.74
SecSurf = graph_view(ax, sigmaI, muI, sigmaV, muV, Imin, Imax, Vmin, Vmax, alpha = 0.8, \
alphaPart = 0.6, colorPart='salmon', color='green')
# square(Imin, Imax, Vmin, Vmax)
# для третьего приступа
sigmaI = 2.398
muI = 10.32
sigmaV = 0.75
muV = -0.625
Imin, Imax = 16.35, 16.55
Vmin, Vmax = 0.359, 0.529
ThirdSurf = graph_view(ax, sigmaI, muI, sigmaV, muV, Imin, Imax, Vmin, Vmax, alpha = 0.7,\
alphaPart = 1, colorPart='navy', color='violet')
# square(Imin, Imax, Vmin, Vmax)
# для первого приступа
sigmaI = 1.7
muI = 12.8
sigmaV = 0.71
muV = -0.554
Imin, Imax = 17.04, 17.49
Vmin, Vmax = 0.6, 0.74
# square(Imin, Imax, Vmin, Vmax)
firstSurf = graph_view(ax, sigmaI, muI, sigmaV, muV, Imin, Imax, Vmin, Vmax, alpha = 0.8,\
alphaPart=1, colorPart='firebrick', color='royalblue')
sigmaI = 1.7
muI = 18
sigmaV = 0.71
muV = 0.9
# graph_view(ax, sigmaI, muI, sigmaV, muV, Imin, Imax, Vmin, Vmax, alpha = 0.4, alphaPart = 0.6, colorPart='salmon', color='dodgerblue')
modelSurf = graph_view_without_part(ax, sigmaI, muI, sigmaV, muV, alpha = 0.4, color='tomato')
firstSurf.set_zorder(4)
SecSurf.set_zorder(3)
ThirdSurf.set_zorder(2)
modelSurf.set_zorder(5)
background(ax)
plt.show()
ASSISTANT
Для достижения более прозрачных поверхностей ближе к нижней плоскости можно воспользоваться функцией `plot_surface` из `matplotlib` и применить к каждому элементу массива прозрачность, которая будет зависеть от его высоты (значения по оси Z).
Ниже приведен пример кода с изменениями, необходимыми для достижения этого эффекта:
1. Обновим функцию `graph_view`, чтобы она рассчитывала значение прозрачности для каждой точки в зависимости от ее высоты.
2. Добавим массив прозрачности `alpha_values`, в котором будем хранить значения прозрачности для каждой точки поверхности.
3. Укажем этот массив в качестве аргумента `alpha` в функции `plot_surface`.
```python
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
def calculate_alpha(z_value, F_min, F_max):
min_alpha = 0.2
max_alpha = 1.0
return min_alpha + (max_alpha - min_alpha) * (z_value - F_min) / (F_max - F_min)
def graph_view(ax, sigmaI, muI, sigmaV, muV, Imin, Imax, Vmin, Vmax, alpha, colorPart, color, alphaPart):
I, V = np.meshgrid(np.linspace(IlimMin, IlimMax, 150), np.linspace(VlimMin, VlimMax, 150))
F = np.exp((-(I-muI)**2-(np.log(V)-muV)**2)/(2 * sigmaI**2 * sigmaV**2))/(sigmaI * sigmaV * V * 2*np.pi)
F_min = F.min()
F_max = F.max()
alpha_values = calculate_alpha(F, F_min, F_max)
surface = ax.plot_surface(I, V, F, facecolors=plt.cm.viridis(F), alpha=alpha_values, edgecolor='none')
max_idx = np.unravel_index(np.argmax(F, axis=None), F.shape)
min_idx = np.unravel_index(np.argmin(F, axis=None), F.shape)
max_F = F[max_idx]
min_F = F[min_idx]
mask = (I >= Imin) & (I <= Imax) & (V >= Vmin) & (V <= Vmax)
x_highlight = np.copy(I)
y_highlight = np.copy(V)
z_highlight = np.copy(F)
x_highlight[~mask] = np.nan
y_highlight[~mask] = np.nan
z_highlight[~mask] = np.nan
alpha_highlight_values = calculate_alpha(z_highlight, F_min, F_max)
highlight_surface = ax.plot_surface(x_highlight, y_highlight, z_highlight, facecolors=plt.cm.viridis(z_highlight), alpha=alpha_highlight_values, edgecolor='none')
ax.set_xlabel('Потребляемый ток')
ax.set_ylabel('Скорость')
ax.set_zlabel('Плотность веростности')
return surface
def graph_view_without_part(ax, sigmaI, muI, sigmaV, muV, alpha, color):
I, V = np.meshgrid(np.linspace(IlimMin, IlimMax, 150), np.linspace(VlimMin, VlimMax, 150))
F1 = np.exp(-0.5*((I-muI)/sigmaI)**2)
F2 = np.exp(-0.5*((V-muV)/sigmaV)**2)
F = F1*F2
F_min = F.min()
F_max = F.max()
alpha_values = calculate_alpha(F, F_min, F_max)
surface = ax.plot_surface(I, V, F, facecolors=plt.cm.viridis(F), alpha=alpha_values, edgecolor='none')
max_idx = np.unravel_index(np.argmax(F, axis=None), F.shape)
max_I = I[max_idx]
max_V = V[max_idx]
max_F = F[max_idx]
print(f"Max I: {max_I}, Max V: {max_V}, Max F: {max_F}")
ax.set_xlabel('Потребляемый ток')
ax.set_ylabel('Скорость')
ax.set_zlabel('Плотность веростности')
return surface
def background(ax):
zmin = 0
square1 = np.array([[0, 0, zmin], [3.33, 0, zmin], [3.33, 0.75, zmin], [0, 0.75, zmin]])
square2 = np.array([[3.33, 0, zmin], [10, 0, zmin], [10, 0.75, zmin], [3.33, 0.75, zmin]])
square3 = np.array([[10, 0, zmin], [16.66, 0, zmin], [16.66, 0.75, zmin], [10, 0.75, zmin]])
square4 = np.array([[16.66, 0, zmin], [20, 0, zmin], [20, 0.75, zmin], [16.66, 0.75, zmin]])
square5 = np.array([[3.33, 0.75, zmin], [10, 0.75, zmin], [10, 2.25, zmin], [3.33, 2.25, zmin]])
square6 = np.array([[10, 0.75, zmin], [16.66, 0.75, zmin], [16.66, 2.25, zmin], [10, 2.25, zmin]])
square7 = np.array([[16.66, 0.75, zmin], [20, 0.75, zmin], [20, 2.25, zmin], [16.66, 2.25, zmin]])
square8 = np.array([[10, 2.25, zmin], [16.66, 2.25, zmin], [16.66, 3.75, zmin], [10, 3.75, zmin]])
square9 = np.array([[16.66, 2.25, zmin], [20, 2.25, zmin], [20, 3.75, zmin], [16.66, 3.75, zmin]])
square10 = np.array([[10, 3.75, zmin], [16.66, 3.75, zmin], [16.66, 4.5, zmin], [10, 4.5, zmin]])
square11 = np.array([[16.66, 3.75, zmin], [20, 3.75, zmin], [20, 4.5, zmin], [16.66, 4.5, zmin]])
sq = [square1, square2, square3, square4, square5, square6, square7, square8, square9, square10, square11]
colors = ['green', 'gold', 'red', 'firebrick', 'gold', 'gold', 'firebrick', 'gold', 'red', 'red', 'red']
for i in range(len(sq)):
square = Poly3DCollection([sq[i]], color=colors[i], edgecolor='none', alpha = 0.5)
ax.add_collection3d(square)
def integrand(I, V):
return np.exp((-(I-muI)**2-(np.log(V)-muV)**2)/(2 * sigmaI**2 * sigmaV**2))/(sigmaI * sigmaV * V * 2*np.pi)
def square(Imin, Imax, Vmin, Vmax):
result, error = integrate.dblquad(integrand, Imin, Imax, lambda x: Vmin, lambda x: Vmax)
print(f"Result: {result}, Error estimate: {error}")
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1, projection='3d', computed_zorder = False)
IlimMin = 0
IlimMax = 20
VlimMin = 0
VlimMax = 4.5
sigmaI = 2.33
muI = 11.46
sigmaV = 0.755
muV = -0.611
Imin, Imax = 17.04, 19.67
Vmin, Vmax = 0.55, 0.74
SecSurf = graph_view(ax, sigmaI, muI, sigmaV, muV, Imin, Imax, Vmin, Vmax, alpha = 0.8, \
alphaPart = 0.6, colorPart='salmon', color='green')
sigmaI = 2.398
muI = 10.32
sigmaV = 0.75
muV = -0.625
Imin, Imax = 16.35, 16.55
Vmin, Vmax = 0.359, 0.529
ThirdSurf = graph_view(ax, sigmaI, muI, sigmaV, muV, Imin, Imax, Vmin, Vmax, alpha = 0.7,\
alphaPart = 1, colorPart='navy', color='violet')
sigmaI = 1.7
muI = 12.8
sigmaV = 0.71
muV = -0.554
Imin, Imax = 17.04, 17.49
Vmin, Vmax = 0.6, 0.74
firstSurf = graph_view(ax, sigmaI, muI, sigmaV, muV, Imin, Imax, Vmin, Vmax, alpha = 0.8,\
alphaPart=1, colorPart='firebrick', color='royalblue')
sigmaI = 1.7
muI = 18
sigmaV = 0.71
muV = 0.9
modelSurf = graph_view_without_part(ax, sigmaI, muI, sigmaV, muV, alpha = 0.4, color='tomato')
firstSurf.set_zorder(4)
SecSurf.set_zorder(3)
ThirdSurf.set_zorder(2)
modelSurf.set_zorder(5)
background(ax)
plt.show()
```
Этот код должен создать поверхности, прозрачность которых будет зависеть от их высоты, создавая эффект большей прозрачности ближе к нижней плоскости.