How to correctly generate a 3d histogram using num

2019-02-25 03:49发布

This is more of a general question about 3d histogram creation in python.

I have attempted to create a 3d histogram using the X and Y arrays in the following code

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

def threedhist():
    X = [1, 3, 5, 8, 6, 7, 1, 2, 4, 5]
    Y = [3, 4, 3, 6, 5, 3, 1, 2, 3, 8]
    fig = pylab.figure()
    ax = Axes3D(fig)
    ax.hist([X, Y], bins=10, range=[[0, 10], [0, 10]])
    plt.xlabel('X')
    plt.ylabel('Y')
    plt.zlabel('Frequency')
    plt.title('Histogram')
    plt.show()

However, I am getting the following error

Traceback (most recent call last):
  File "<pyshell#0>", line 1, in <module>
    a3dhistogram()
  File "C:/Users/ckiser/Desktop/Projects/Tom/Python Files/threedhistogram.py", line 24, in a3dhistogram
    ax.hist([X, Y], bins=10, range=[[0, 10], [0, 10]])
  File "C:\Python27\lib\site-packages\matplotlib\axes.py", line 7668, in hist
    m, bins = np.histogram(x[i], bins, weights=w[i], **hist_kwargs)
  File "C:\Python27\lib\site-packages\numpy\lib\function_base.py", line 169, in histogram
    mn, mx = [mi+0.0 for mi in range]
TypeError: can only concatenate list (not "float") to list

I have tried the code with and without the "[" in the line ax.hist([X, Y], bins=10, range=[[0, 10], [0, 10]]) I have also tried the function from numpy without success H, xedges, yedges = np.histogram2d(x, y, bins = (10, 10)) Am I missing a step or a parameter? Any advice would be greatly appreciated.

标签: 3d histogram
4条回答
小情绪 Triste *
2楼-- · 2019-02-25 04:32

I've added to @lxop's answer to allow for arbitrary size buckets:

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 = np.array([0, 2, 5, 10, 2, 3, 5, 2, 8, 10, 11])
y = np.array([0, 2, 5, 10, 6, 4, 2, 2, 5, 10, 11])
# This example actually counts the number of unique elements.
binsOne = sorted(set(x))
binsTwo = sorted(set(y))
# Just change binsOne and binsTwo to lists.
hist, xedges, yedges = np.histogram2d(x, y, bins=[binsOne, binsTwo])

# The start of each bucket.
xpos, ypos = np.meshgrid(xedges[:-1], yedges[:-1])

xpos = xpos.flatten()
ypos = ypos.flatten()
zpos = np.zeros_like(xpos)

# The width of each bucket.
dx, dy = np.meshgrid(xedges[1:] - xedges[:-1], yedges[1:] - yedges[:-1])

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

ax.bar3d(xpos, ypos, zpos, dx, dy, dz, color='b', zsort='average')
查看更多
时光不老,我们不散
3楼-- · 2019-02-25 04:33

Have a look at http://matplotlib.sourceforge.net/examples/mplot3d/hist3d_demo.html, this has a working example script.

I've improved the code at that link to be more of a histogram:

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, 3, 5, 8, 6, 7, 1, 2, 4, 5]
y = [3, 4, 3, 6, 5, 3, 1, 2, 3, 8]

hist, xedges, yedges = np.histogram2d(x, y, bins=(4,4))
xpos, ypos = np.meshgrid(xedges[:-1]+xedges[1:], yedges[:-1]+yedges[1:])

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

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

ax.bar3d(xpos, ypos, zpos, dx, dy, dz, color='b', zsort='average')
plt.xlabel ("X")
plt.ylabel ("Y")

plt.show()

I'm not sure how to do it with Axes3D.hist ().

查看更多
甜甜的少女心
4楼-- · 2019-02-25 04:38

In this answer there is a solution for 2D and 3D Histograms of scattered points. The usage is simple:

points, sub = hist2d_scatter( radius, density, bins=4 )

points, sub = hist3d_scatter( temperature, density, radius, bins=4 )

Where sub is a matplotlib "Subplot" instance (3D or not) and pointscontains the points used for the scatter plot.

查看更多
够拽才男人
5楼-- · 2019-02-25 04:44

I posted this in a related thread about colored 3d bar plots, but I think it's also relevant here as I couldn't find a complete answer for what I needed in either thread. This code generates a histogram scatterplot for any sort of x-y data. The height represents the frequency of values in that bin. So, for example, if you had many data point where (x,y) = (20,20) it would be high and red. If you had few data points in the bin where (x,y) = (100,100) it would be low and blue.

Note: result will vary substantially depending on how much data you have and how many bins your choose for you histogram. Adjust accordingly!

xAmplitudes = #your data here
yAmplitudes = #your other data here

x = np.array(xAmplitudes)   #turn x,y data into numpy arrays
y = np.array(yAmplitudes)

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

#make histogram stuff - set bins - I choose 20x20 because I have a lot of data
hist, xedges, yedges = np.histogram2d(x, y, bins=(20,20))
xpos, ypos = np.meshgrid(xedges[:-1]+xedges[1:], yedges[:-1]+yedges[1:])

xpos = xpos.flatten()/2.
ypos = ypos.flatten()/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()

The results for about 75k data points of mine are below. Note, you can drag and drop to different perspectives and may want to save multiple views for presentations, posterity.

3d histogram side view 3d histogram perspective 2

查看更多
登录 后发表回答