Как построить трехмерную гистограмму с помощью matplotlib/mplot3d?

У меня есть три массива, и я пытаюсь сделать трехмерную гистограмму.

x = [1, 2, 3, 2, 5, 2, 6, 8, 6, 7]
y = [10, 10, 20, 50, 20, 20, 30, 10, 40, 50, 60]
z = [105, 25, 26, 74, 39, 85, 74, 153, 52, 98]

Вот моя попытка:

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure()
ax = plt.axes(projection='3d')

binsOne = sorted(set(x))
binsTwo = sorted(set(y))
hist, xedges, yedges = np.histogram2d(x, y, bins=[binsOne, binsTwo])
xpos, ypos = np.meshgrid(xedges[:-1] + 0.25 , yedges[:-1] + 0.25)
xpos = xpos.flatten('F')
ypos = ypos.flatten('F')
zpos = np.zeros_like(xpos)

dx = dx.flatten()
dy = dy.flatten()
dz = hist.flatten()

ax.bar3d(xpos, ypos, zpos, dx, dy, dz, color='b', zsort='average')

Как включить массив z в мою трехмерную гистограмму?


person Matt-pow    schedule 02.01.2019    source источник
comment
Я советую вам этот пост: stackoverflow.com/questions/53611716 / У Matplotlib есть некоторые проблемы с 3D-графикой, так что обратите внимание!   -  person Alessandro Peca    schedule 03.01.2019


Ответы (1)


Массив z должен иметь одинаковую форму не с x и y, а с xpos и ypos (которые сами по себе имеют одинаковую форму). Вы можете найти этот пример более полезным, чем тот, который вам кажется рисунок из. Следующий код предназначен для демонстрации примера в первой ссылке, примененной к вашему вопросу,

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

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

_x = [1, 2, 3, 2, 5, 2, 6, 8, 6, 7]
_y = [10, 10, 20, 50, 20, 20, 30, 10, 40, 50]
_xx, _yy = np.meshgrid(_x, _y)
x, y = _xx.ravel(), _yy.ravel()
_z = np.array([105, 25, 26, 74, 39, 85, 74, 153, 52, 98])

# There may be an easier way to do this, but I am not aware of it
z = np.zeros(len(x))
for i in range(1, len(x)):
    z[i] = _z[(i*len(_z)) / len(x)]

bottom = np.zeros_like(z)
width = depth = 1

ax.bar3d(x, y, bottom, width, depth, z, shade=True)
plt.show()

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

person William Miller    schedule 03.01.2019
comment
Спасибо за ваш ответ, почему z не следует за x и y в ax.bar3d? Также можете ли вы объяснить мне, что делает цикл for для _z? - person Matt-pow; 03.01.2019
comment
@ Matt-pow Я не понимаю вашего вопроса, значения z в массиве определяют высоту полосы, значения x определяют положение x, а значения y определяют положение y. Для пар x и y, которые соответствуют общему значению z, вы видите несколько полос. Значения на осях y и x немного сбивают с толку, поскольку полоса 1 в x на самом деле идет от 1 до 2, а 8 идет от 8 до 9. - person William Miller; 03.01.2019
comment
@Matt-pow Цикл for для _z преобразует _z массив формы (10L, ) в z массив формы (100L, ), заполненный 10 экземплярами каждого значения. - person William Miller; 03.01.2019
comment
Спасибо за объяснение - person Matt-pow; 04.01.2019