How to correctly generate a three-dimensional histogram using numpy or matplotlib built-in functions in python?

This is a more general question about creating 3D histograms in python.

I tried to create a three-dimensional histogram using 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 get 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 tried the code with and without "[" in the line ax.hist ([X, Y], bit = 10, range = [[0, 10], [0, 10]]) I also tried the function from numpy without success H , xedges, yedges = np.histogram2d (x, y, bins = (10, 10)) Am I missing a step or parameter? Any advice would be greatly appreciated.

+3
source share
4 answers

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

I improved the code on this link to be a histogram more:

 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 am not sure how to do this with Axes3D.hist ().

+1
source

In this answer there is a solution for two-dimensional and three-dimensional histograms of scattered points. The use is simple:

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

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

+1
source

I added an @lxop answer to allow buckets of arbitrary size:

 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') 
+1
source

I posted this on the related topic of 3d bar color charts, but I think it is also relevant here, since I could not find the full answer for what I needed in any thread. This code generates a histogram scatter plot for any xy data. Height is the frequency of the values ​​in this bin. So, for example, if you had many data points, where (x, y) = (20,20) would be high and red. If you had several data points in a bin, where (x, y) = (100,100), that would be low and blue.

Note: the result will differ significantly depending on how much data you have and how many bins you have selected for you with a 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 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() 

Below are the results for about 75 thousand data points. Please note that you can drag and drop to different points of view and may want to save several views for presentations, descendants.

3d histogram side view 3d histogram perspective 2

+1
source

All Articles