Anonymous
Добавить контур к трехмерной диаграмме
Сообщение
Anonymous » 02 мар 2026, 06:45
Поэтому я работал с ChatGPT над созданием трехмерной гистограммы с эффектом градиента в Python.
Я столкнулся с проблемой: я не могу добавлять контуры к столбцам. Если я это сделаю, панель станет прозрачной. GPT говорит, что это проблема matplotlib. Как я могу это исправить? Спасибо.
Это исходный код прототипа:
Код: Выделить всё
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.colors as mcolors
models = ['1', '2', '3', '4', '5']
scenarios = ['Scenario 1', 'Scenario 2', 'Scenario 3']
performance = [
[0.794, 0.732, 0.665],
[0.783, 0.722, 0.664],
[0.786, 0.729, 0.664],
[0.799, 0.732, 0.667],
[0.704, 0.696, 0.669],
]
performance = np.array(performance)
performanceT = performance.T
xpos = np.array([0, 1, 2, 3, 4])
ypos = np.array([0, 0.5, 1])
xposM, yposM = np.meshgrid(xpos, ypos, copy=False)
zpos = performanceT.ravel()
dx = 0.8
dy = 0.4
dz = zpos
scenario_colors = ['#377e22', '#0480A6', '#FF0000']
colors = []
for i in range(len(scenarios)):
for j in range(len(models)):
colors.append(scenario_colors[i])
colors = np.array(colors)
fig = plt.figure(figsize=(10, 10), dpi=300)
ax1 = fig.add_subplot(111, projection='3d')
ax1.set_xlabel('Models', labelpad=10)
ax1.set_ylabel('Scenarios', labelpad=10)
ax1.set_zlabel('Precision 1')
n_layers = 80
x_flat = xposM.ravel()
y_flat = yposM.ravel()
z_flat = dz
max_height = 1#dz.max()
layers = 100
for idx in range(len(dz)):
x = xposM.ravel()[idx]
y = yposM.ravel()[idx]
height = dz[idx]
scenario_index = idx // len(models)
base_color = np.array(to_rgb(scenario_colors[scenario_index]))
yellow = np.array(to_rgb("yellow"))
step = height / layers
z_current = 0
for k in range(layers):
z_top = z_current + step
ratio = z_top / max_height
color = base_color * (1 - ratio) + yellow * ratio
color = np.clip(color, 0, 1)
ax1.bar3d(
x,
y,
z_current,
dx,
dy,
step,
color=color,
edgecolor=None,
shade=False
)
z_current = z_top
ax1.set_xticks(xpos + dx/2)
ax1.set_xticklabels(models, rotation=30, ha='right')
ax1.set_yticks(ypos + dy/2)
ax1.set_yticklabels(scenarios)
ax1.set_proj_type('ortho')
ax1.set_box_aspect((1, 1, 0.6))
ax1.view_init(elev=25, azim=60)
plt.tight_layout()
plt.show()
Вот прозрачные полосы с контуром:
Код: Выделить всё
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import to_rgb
# =============================
# Data
# =============================
models = ['1', '2', '3', '4', '5']
scenarios = ['Scenario 1', 'Scenario 2', 'Scenario 3']
performance = [
[0.794, 0.732, 0.665],
[0.783, 0.722, 0.664],
[0.786, 0.729, 0.664],
[0.799, 0.732, 0.667],
[0.704, 0.696, 0.669],
]
performance = np.array(performance)
performanceT = performance.T # shape (3,5)
# =============================
# Figure
# =============================
fig = plt.figure(figsize=(10, 10), dpi=300)
ax1 = fig.add_subplot(111, projection='3d')
ax1.set_xlabel('Models', labelpad=10)
ax1.set_ylabel('Scenarios', labelpad=10)
ax1.set_zlabel('Precision 1')
xpos = np.array([0,1,2,3,4])
ypos = np.array([0, 0.5, 1])
xposM, yposM = np.meshgrid(xpos, ypos, copy=False)
dx = 0.8
dy = 0.4
dz = performanceT.ravel()
max_height = dz.max()
scenario_colors = ['#377e22', '#0480A6', '#FF0000']
yellow = np.array(to_rgb("yellow"))
#yellow = np.array(to_rgb("#F4D03F"))
layers = 100
# =============================
# Gradient Bars
# =============================
max_height = 1#dz.max()
layers = 100
for idx in range(len(dz)):
x = xposM.ravel()[idx]
y = yposM.ravel()[idx]
height = dz[idx]
scenario_index = idx // len(models)
base_color = np.array(to_rgb(scenario_colors[scenario_index]))
yellow = np.array(to_rgb("yellow"))
step = height / layers
z_current = 0
for k in range(layers):
z_top = z_current + step
ratio = z_top / max_height
color = base_color * (1 - ratio) + yellow * ratio
color = np.clip(color, 0, 1)
ax1.bar3d(
x,
y,
z_current,
dx,
dy,
step,
color=color,
edgecolor=None,
shade=False
)
z_current = z_top
# =============================
# Add Black Outline Once
# =============================
ax1.bar3d(
xposM.ravel(),
yposM.ravel(),
dz*0,
dx,
dy,
dz,
color=(0,0,0,0),
edgecolor='black',
linewidth=0.1,
shade=False
)
# =============================
# Axis Ticks
# =============================
ax1.set_xticks(xpos + dx/2)
ax1.set_xticklabels(models, rotation=20, ha='right')
ax1.set_yticks(ypos + dy/2)
ax1.set_yticklabels(scenarios)
# =============================
# View & Style
# =============================
ax1.set_proj_type('ortho')
ax1.set_box_aspect((1,1,0.6))
ax1.view_init(elev=25, azim=60)
plt.tight_layout()
plt.show()`
`
Подробнее здесь:
https://stackoverflow.com/questions/798 ... d-barchart
1772423138
Anonymous
Поэтому я работал с ChatGPT над созданием трехмерной гистограммы с эффектом градиента в Python. Я столкнулся с проблемой: я не могу добавлять контуры к столбцам. Если я это сделаю, панель станет прозрачной. GPT говорит, что это проблема matplotlib. Как я могу это исправить? Спасибо. Это исходный код прототипа: [code]import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D import matplotlib.colors as mcolors models = ['1', '2', '3', '4', '5'] scenarios = ['Scenario 1', 'Scenario 2', 'Scenario 3'] performance = [ [0.794, 0.732, 0.665], [0.783, 0.722, 0.664], [0.786, 0.729, 0.664], [0.799, 0.732, 0.667], [0.704, 0.696, 0.669], ] performance = np.array(performance) performanceT = performance.T xpos = np.array([0, 1, 2, 3, 4]) ypos = np.array([0, 0.5, 1]) xposM, yposM = np.meshgrid(xpos, ypos, copy=False) zpos = performanceT.ravel() dx = 0.8 dy = 0.4 dz = zpos scenario_colors = ['#377e22', '#0480A6', '#FF0000'] colors = [] for i in range(len(scenarios)): for j in range(len(models)): colors.append(scenario_colors[i]) colors = np.array(colors) fig = plt.figure(figsize=(10, 10), dpi=300) ax1 = fig.add_subplot(111, projection='3d') ax1.set_xlabel('Models', labelpad=10) ax1.set_ylabel('Scenarios', labelpad=10) ax1.set_zlabel('Precision 1') n_layers = 80 x_flat = xposM.ravel() y_flat = yposM.ravel() z_flat = dz max_height = 1#dz.max() layers = 100 for idx in range(len(dz)): x = xposM.ravel()[idx] y = yposM.ravel()[idx] height = dz[idx] scenario_index = idx // len(models) base_color = np.array(to_rgb(scenario_colors[scenario_index])) yellow = np.array(to_rgb("yellow")) step = height / layers z_current = 0 for k in range(layers): z_top = z_current + step ratio = z_top / max_height color = base_color * (1 - ratio) + yellow * ratio color = np.clip(color, 0, 1) ax1.bar3d( x, y, z_current, dx, dy, step, color=color, edgecolor=None, shade=False ) z_current = z_top ax1.set_xticks(xpos + dx/2) ax1.set_xticklabels(models, rotation=30, ha='right') ax1.set_yticks(ypos + dy/2) ax1.set_yticklabels(scenarios) ax1.set_proj_type('ortho') ax1.set_box_aspect((1, 1, 0.6)) ax1.view_init(elev=25, azim=60) plt.tight_layout() plt.show() [/code] [img]https://i.sstatic.net/w4uTMnY8.png[/img] Вот прозрачные полосы с контуром: [code]import numpy as np import matplotlib.pyplot as plt from matplotlib.colors import to_rgb # ============================= # Data # ============================= models = ['1', '2', '3', '4', '5'] scenarios = ['Scenario 1', 'Scenario 2', 'Scenario 3'] performance = [ [0.794, 0.732, 0.665], [0.783, 0.722, 0.664], [0.786, 0.729, 0.664], [0.799, 0.732, 0.667], [0.704, 0.696, 0.669], ] performance = np.array(performance) performanceT = performance.T # shape (3,5) # ============================= # Figure # ============================= fig = plt.figure(figsize=(10, 10), dpi=300) ax1 = fig.add_subplot(111, projection='3d') ax1.set_xlabel('Models', labelpad=10) ax1.set_ylabel('Scenarios', labelpad=10) ax1.set_zlabel('Precision 1') xpos = np.array([0,1,2,3,4]) ypos = np.array([0, 0.5, 1]) xposM, yposM = np.meshgrid(xpos, ypos, copy=False) dx = 0.8 dy = 0.4 dz = performanceT.ravel() max_height = dz.max() scenario_colors = ['#377e22', '#0480A6', '#FF0000'] yellow = np.array(to_rgb("yellow")) #yellow = np.array(to_rgb("#F4D03F")) layers = 100 # ============================= # Gradient Bars # ============================= max_height = 1#dz.max() layers = 100 for idx in range(len(dz)): x = xposM.ravel()[idx] y = yposM.ravel()[idx] height = dz[idx] scenario_index = idx // len(models) base_color = np.array(to_rgb(scenario_colors[scenario_index])) yellow = np.array(to_rgb("yellow")) step = height / layers z_current = 0 for k in range(layers): z_top = z_current + step ratio = z_top / max_height color = base_color * (1 - ratio) + yellow * ratio color = np.clip(color, 0, 1) ax1.bar3d( x, y, z_current, dx, dy, step, color=color, edgecolor=None, shade=False ) z_current = z_top # ============================= # Add Black Outline Once # ============================= ax1.bar3d( xposM.ravel(), yposM.ravel(), dz*0, dx, dy, dz, color=(0,0,0,0), edgecolor='black', linewidth=0.1, shade=False ) # ============================= # Axis Ticks # ============================= ax1.set_xticks(xpos + dx/2) ax1.set_xticklabels(models, rotation=20, ha='right') ax1.set_yticks(ypos + dy/2) ax1.set_yticklabels(scenarios) # ============================= # View & Style # ============================= ax1.set_proj_type('ortho') ax1.set_box_aspect((1,1,0.6)) ax1.view_init(elev=25, azim=60) plt.tight_layout() plt.show()` ` [/code] [img]https://i.sstatic.net/feiGVZ6t.png[/img] Подробнее здесь: [url]https://stackoverflow.com/questions/79895361/add-outline-to-the-3d-barchart[/url]