用python绘制3D条形图 [英] Plot a 3D bar histogram with python

查看:389
本文介绍了用python绘制3D条形图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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

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

#生成一些测试数据
x = np.random.randn(500)
y = np.random.randn(500)

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

def选择(XY,limitXY = [[-2,+ 2],[-2,+ 2]]):
XY_select = []
表示yel :如果elt [0]>
limitXY [0] [0]和elt [0]< limitXY [0] [1]和elt [1]> limitXY [1] [0]和elt [1]< limitXY [1] [1]:
XY_select.append(elt)

返回np.array(XY_select)

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

热图,xedges,yedges = np.histogram2d(XY_select [:,0],XY_select [:,1],bins = 7,范围= [[-2,2],[-2,2]])
范围= [xedges [0],xedges [-1],yedges [0],yedges [-1]]


plt.figure(直方图)
#plt.clf()
plt.imshow(heatmap.T,range = extent,origin ='lower ')
plt.show()

给出正确的结果:





现在,我想将其转换为3D直方图。不幸的是,我无法成功使用 bar3d 正确绘制它,因为默认情况下,它需要使用x和y的长度来表示脱落。



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

解决方案

我最终成功做到了。我几乎可以肯定有更好的方法可以做到这一点,但在有效的情况下:

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

#生成一些测试数据
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 = []
表示yel XY:
如果elt [0]> limitXY [0] [0]和elt [0]< limitXY [0] [1]和elt [1]> limitXY [1] [0]和elt [1]< limitXY [1] [1]:
XY_select.append(elt)

返回np.array(XY_select)

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


xAmplitudes = np.array(XY_select)[:, 0]#此处的数据
yAmplitudes = np.array(XY_select)[:, 1]#此处的其他数据


图= plt.figure()#创建画布,告诉matplotlib它是3d
ax = fig.add_subplot(111,projection ='3d')


hist,xedges,yedges = np.histogram2d(x,y,bins =(7,7),range = [[-2,+ 2],[-2,+ 2]])#您可以更改垃圾箱,并且获取数据的范围
#hist是7X7矩阵,其中每个人口子空间部分。
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 / 2
zpos = np.zeros_like( xpos)

dx =边缘[1]-边缘[0]
dy =边缘[1]-边缘[0]
dz = hist.flatten()

cmap = cm.get_cmap('jet')#获取所需的颜色图-您可以更改它!
max_height = np.max(dz)#获取颜色条的范围,因此我们可以规范化
min_height = np.min(dz)
#将每个z缩放为[0,1],并获得它们的rgb值
rgba = [d中k中的k的cmap((k-min_height)/ max_height)]

ax.bar3d(xpos,ypos,zpos,dx,dy,dz,颜色= rgba,zsort ='average')
plt.title( ____数据的X与Y幅度)
plt.xlabel(我的X数据源)
plt.ylabel (我的Y数据源)
plt.savefig( Your_title_goes_here)
plt.show()

我使用以下


I have some x and y data, with which I would like to generate a 3D histogram, with a color gradient (bwr or whatever).

I have written a script which plot the interesting values, in between -2 and 2 for both x and y abscesses:

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()

And give this correct result:

Now, I would like to turn this into a 3D histogram. Unfortunatly I don't success to plot it correctly with bar3d because it takes by default the length of x and y for abscisse.

I am quite sure that there is a very easy way to plot this in 3D with imshow. Like an unknow option...

解决方案

I finaly succeded in doing it. I am almost sure there is a better way to do it, but at leat it works:

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()

I use this example, but I modified it, because it introduced an offset. The result is this:

这篇关于用python绘制3D条形图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆