天天看點

python繪制三維條形圖_用python繪制3D條形圖

python繪制三維條形圖_用python繪制3D條形圖

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:

python繪制三維條形圖_用python繪制3D條形圖

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繪制三維條形圖_用python繪制3D條形圖