2D and 3D scatter histograms from arrays in Python

Do you have any ideas how I can bin 3 arrays on a histogram. My arrays look like

Temperature = [4, 3, 1, 4, 6, 7, 8, 3, 1] Radius = [0, 2, 3, 4, 0, 1, 2, 10, 7] Density = [1, 10, 2, 24, 7, 10, 21, 102, 203] 

And the 1D chart should look:

 Density | X 10^2-| X | X 10^1-| | X 10^0-| |___|___|___|___|___ Radius 0 3.3 6.6 10 

And the 2D plot should look (quality):

 Density | 2 | | 10^2-| 11249 | | | 233 | | Radius 10^1-| 12 | | | 1 | | 10^0-| |___|___|___|___|___ Temperature 0 3 5 8 

So, I want one or two fields with python / numpy, and then draw them to analyze their correspondence.

+7
source share
2 answers

Here it follows two functions: hist2d_bubble and hist3d_bubble ; which may fit your purpose:

enter image description here

 import numpy as np import matplotlib.pyplot as pyplot from mpl_toolkits.mplot3d import Axes3D def hist2d_bubble(x_data, y_data, bins=10): ax = np.histogram2d(x_data, y_data, bins=bins) xs = ax[1] ys = ax[2] points = [] for (i, j), v in np.ndenumerate(ax[0]): points.append((xs[i], ys[j], v)) points = np.array(points) fig = pyplot.figure() sub = pyplot.scatter(points[:, 0],points[:, 1], color='black', marker='o', s=128*points[:, 2]) sub.axes.set_xticks(xs) sub.axes.set_yticks(ys) pyplot.ion() pyplot.grid() pyplot.show() return points, sub def hist3d_bubble(x_data, y_data, z_data, bins=10): ax1 = np.histogram2d(x_data, y_data, bins=bins) ax2 = np.histogram2d(x_data, z_data, bins=bins) ax3 = np.histogram2d(z_data, y_data, bins=bins) xs, ys, zs = ax1[1], ax1[2], ax3[1] smart = np.zeros((bins, bins, bins),dtype=int) for (i1, j1), v1 in np.ndenumerate(ax1[0]): if v1 == 0: continue for k2, v2 in enumerate(ax2[0][i1]): v3 = ax3[0][k2][j1] if v1 == 0 or v2 == 0 or v3 == 0: continue num = min(v1, v2, v3) smart[i1, j1, k2] += num v1 -= num v2 -= num v3 -= num points = [] for (i, j, k), v in np.ndenumerate(smart): points.append((xs[i], ys[j], zs[k], v)) points = np.array(points) fig = pyplot.figure() sub = fig.add_subplot(111, projection='3d') sub.scatter(points[:, 0], points[:, 1], points[:, 2], color='black', marker='o', s=128*points[:, 3]) sub.axes.set_xticks(xs) sub.axes.set_yticks(ys) sub.axes.set_zticks(zs) pyplot.ion() pyplot.grid() pyplot.show() return points, sub 

The two numbers above were created using:

 temperature = [4, 3, 1, 4, 6, 7, 8, 3, 1] radius = [0, 2, 3, 4, 0, 1, 2, 10, 7] density = [1, 10, 2, 24, 7, 10, 21, 102, 203] import matplotlib matplotlib.rcParams.update({'font.size':14}) points, sub = hist2d_bubble(radius, density, bins=4) sub.axes.set_xlabel('radius') sub.axes.set_ylabel('density') points, sub = hist3d_bubble(temperature, density, radius, bins=4) sub.axes.set_xlabel('temperature') sub.axes.set_ylabel('density') sub.axes.set_zlabel('radius') 

on this topic:

Howto bin a series of float values ​​in a histogram in Python?

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

2D Bar Graph with Python

+11
source

here's a two-dimensional version of Castro code above. It just displays the average value at each x, y coordinate. This can be built using imshow, but the Castro approach makes a much more accurate scatter plot.

 from matplotlib import pyplot as plt import numpy as np # make some x,y points and z data that needs to be averaged and plotted x = [1,1,1,2,2,2,2,3,4,4,4,4] y = [1,1,1,2,2,2,2,3,4,4,4,4] z = [1,1,1,2,2,3,3,4,4,4,5,5] xbins, ybins = int(max(x)), int(max(y)) rng = [[1, xbins+1], [1, ybins+1]] bins = [xbins,ybins] # get the sum of weights and sum of occurrences (their division gives the mean) H, xs, ys =np.histogram2d(x, y, weights=z, bins=bins, range=rng) count, _, _ =np.histogram2d(x, y, bins=bins, range=rng) # get the mean value of each x,y point count = np.ma.masked_where(count==0,count) H = np.ma.masked_where(H==0,H) H/=count # separate the H matrix into x,y,z arrays (and discard zero values) points = [] for (i, j),v in np.ndenumerate(H): if v: points.append((xs[i], ys[j], v)) points = np.array(points) # plot the data fig = plt.figure() cm = plt.cm.get_cmap('hot') p = plt.scatter(points[:, 0], points[:, 1], c=points[:, 2], cmap=cm) plt.colorbar(p).set_label('avg. z value') plt.grid() plt.show() 

All duplicated points x, y are now reduced to a unique set and their z values ​​are averaged:

averaged z value of duplicated x, y coordinates

+1
source

All Articles