【问题标题】:Plot a 3D bar histogram with python用python绘制一个3D条形直方图
【发布时间】:2019-02-22 09:57:13
【问题描述】:

我有一些 x 和 y 数据,我想用它们生成一个带有颜色渐变(bwr 或其他)的 3D 直方图。

我编写了一个脚本,它绘制了 x 和 y 脓肿的有趣值,介于 -2 和 2 之间:

import numpy as np
import numpy.random
import matplotlib.pyplot as plt

# To generate some test data
x = np.random.randn(500)
y = np.random.randn(500)

XY = np.stack((x,y),axis=-1)

def selection(XY, limitXY=[[-2,+2],[-2,+2]]):
        XY_select = []
        for elt in XY:
            if elt[0] > limitXY[0][0] and elt[0] < limitXY[0][1] and elt[1] > limitXY[1][0] and elt[1] < limitXY[1][1]:
                XY_select.append(elt)

        return np.array(XY_select)

XY_select = selection(XY, limitXY=[[-2,+2],[-2,+2]])

heatmap, xedges, yedges = np.histogram2d(XY_select[:,0], XY_select[:,1], bins = 7, range = [[-2,2],[-2,2]])
extent = [xedges[0], xedges[-1], yedges[0], yedges[-1]]


plt.figure("Histogram")
#plt.clf()
plt.imshow(heatmap.T, extent=extent, origin='lower')
plt.show()

并给出正确的结果:

现在,我想将其转换为 3D 直方图。不幸的是,我没有成功地用bar3d 正确绘制它,因为默认情况下它采用横坐标的 x 和 y 的长度。

我很确定有一种非常简单的方法可以使用 imshow 以 3D 形式进行绘制。就像一个未知的选项...

【问题讨论】:

  • 除非你使用mplot3d,否则matplotlib 不具备3d 绘图功能。
  • 你查过官方docs吗?有一个简单的例子。
  • 我不明白这个 x,y 数据的用途。我猜你有一个等间距的网格,网格上的每个正方形都应该得到一些随机值。
  • 致 norok2:是的,我看过,但示例(如您的示例)不符合我的要求...
  • 链接的例子似乎是直接适用的。如果那是“不是我想要的”,你会想告诉在多远它不是,否则人们无法知道这有什么问题。 (如果你想通知某人,请使用@username,否则他们不会看到)

标签: python-2.7 matplotlib 3d histogram


【解决方案1】:

我终于成功了。我几乎可以肯定有更好的方法来做到这一点,但至少它有效:

import numpy as np
import numpy.random
import matplotlib.pyplot as plt

# To generate some test data
x = np.random.randn(500)
y = np.random.randn(500)

XY = np.stack((x,y),axis=-1)

def selection(XY, limitXY=[[-2,+2],[-2,+2]]):
        XY_select = []
        for elt in XY:
            if elt[0] > limitXY[0][0] and elt[0] < limitXY[0][1] and elt[1] > limitXY[1][0] and elt[1] < limitXY[1][1]:
                XY_select.append(elt)

        return np.array(XY_select)

XY_select = selection(XY, limitXY=[[-2,+2],[-2,+2]])


xAmplitudes = np.array(XY_select)[:,0]#your data here
yAmplitudes = np.array(XY_select)[:,1]#your other data here


fig = plt.figure() #create a canvas, tell matplotlib it's 3d
ax = fig.add_subplot(111, projection='3d')


hist, xedges, yedges = np.histogram2d(x, y, bins=(7,7), range = [[-2,+2],[-2,+2]]) # you can change your bins, and the range on which to take data
# hist is a 7X7 matrix, with the populations for each of the subspace parts.
xpos, ypos = np.meshgrid(xedges[:-1]+xedges[1:], yedges[:-1]+yedges[1:]) -(xedges[1]-xedges[0])


xpos = xpos.flatten()*1./2
ypos = ypos.flatten()*1./2
zpos = np.zeros_like (xpos)

dx = xedges [1] - xedges [0]
dy = yedges [1] - yedges [0]
dz = hist.flatten()

cmap = cm.get_cmap('jet') # Get desired colormap - you can change this!
max_height = np.max(dz)   # get range of colorbars so we can normalize
min_height = np.min(dz)
# scale each z to [0,1], and get their rgb values
rgba = [cmap((k-min_height)/max_height) for k in dz] 

ax.bar3d(xpos, ypos, zpos, dx, dy, dz, color=rgba, zsort='average')
plt.title("X vs. Y Amplitudes for ____ Data")
plt.xlabel("My X data source")
plt.ylabel("My Y data source")
plt.savefig("Your_title_goes_here")
plt.show()

我使用这个example,但我修改了它,因为它引入了一个偏移量。结果是这样的:

【讨论】:

  • 干得好!我在应用配色方案时遇到了麻烦。感谢分享
  • @kanayamalakar 但颜色的重新归一化存在问题...如果在此行之后 'hist, xedges, yedges = np.histogram2d(x, y, bins=(7,7) , range = [[-2,+2],[-2,+2]]) # 你可以改变你的箱子,和取数据的范围'你用另一个 7X7 矩阵替换 hist,颜色不是不再规模化。我不明白为什么!应该有更好的方法来获得这种颜色渐变。
  • 或许可以加上“import matplotlib.cm as cm”
【解决方案2】:

您可以使用以下简单的方法生成相同的结果:

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(-2, 2, 7)
y = np.linspace(-2, 2, 7)

xx, yy = np.meshgrid(x, y)

z = xx*0+yy*0+ np.random.random(size=[7,7])

plt.imshow(z, interpolation='nearest', cmap=plt.cm.viridis, extent=[-2,2,2,2])
plt.show()

from mpl_toolkits.mplot3d import Axes3D
ax = Axes3D(plt.figure())

ax.plot_surface(xx, yy, z, cmap=plt.cm.viridis, cstride=1, rstride=1)
plt.show()

结果如下:

【讨论】:

  • 对不起,如果您使用相同的 x、y 和 heatmap.T 数据会更好。你改变 exep
  • 谢谢!但是很抱歉,如果您使用相同的 x、y 和 heatmap.T 数据会更好。你稍微改变一下这个例子。另外,我们可以有一些平坦的水平而不是倾斜表面吗?
  • 另外,还有一个我之前没有注意到的问题:2D 彩色直方图有 7x7 的分界线,而另一个有 6 个分界线!这使得观察数据分析变得很危险......很棒的是3D的7x7平面正方形级别。 @kanayamalakar
  • @AgapeGal'lo,你能给我看一张你想要的 3D 情节的图片吗?也许只是一个代表性的情节?因为我似乎不明白你所说的 3D 平面方形关卡是什么意思。
  • 2D 和 3D 绘图的区别是:在 2D 中,数据点位于每个框的中心。而在 3D 中,数据点位于框的角落。线段连接相邻的数据点并形成网格。因此,对于 7x7 数据点,您将获得 (7-1)x(7-1) 大小的网格。
猜你喜欢
  • 2023-04-01
  • 1970-01-01
  • 2015-07-12
  • 1970-01-01
  • 2010-12-28
  • 1970-01-01
  • 2012-09-13
  • 1970-01-01
  • 2020-01-06
相关资源
最近更新 更多