Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

3D histograms and Contour plots Python

I have a problem with contourf function of matplotlib. I have a txt data file from which I am importing my data. I have columns of data (pm1 and pm2) and I am performing a 2D histogram. I want to plot this data as a 3D histogram and as a contour plot to see where is located the maximum values.

This is my code:

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
rows = np.arange(200,1300,10)

hist, xedges, yedges = np.histogram2d (pm1_n, pm2_n, bins = (rows, rows) )
elements = (len(xedges) - 1) * (len(yedges) - 1)


xpos, ypos = np.meshgrid(xedges[:-1], yedges[:-1])

xpos = xpos.flatten()
ypos = ypos.flatten()
zpos = np.zeros(elements)
dx = 0.1 * np.ones_like(zpos)
dy = dx.copy()
dz = hist.flatten()

#####The problem is here#####

#ax.contourf(xpos,ypos,hist)
#ax.bar3d(xpos, ypos, zpos, dx, dy, dz, zsort='average')

plt.show()

I can plot the 3d bar graph but I am not able to plot the contour one, If I place hist in the contourf function I get the error: Length of x must be number of columns in z and if I place dz I get Input z must be a 2D array I also have tried using xedges and yexges but this doesn't solve the problem.

I think that the problem is related with the shape of the return of the function histogram2D. But I don't know how to solve it.

I would also like to perform a 3D bar plot with a colorcode changing form the minimum to the maximum value. Is there anyway to make this?

Thank you

like image 317
Kilian A.G. Avatar asked Nov 09 '22 17:11

Kilian A.G.


1 Answers

Perhaps I don't understand what exactly you are trying to do since I don't know what your data looks like, but it seems wrong to have your contourf plot sharing the same axis as your bar3d plot. If you add an axis without the 3D projection to a new figure, you should be able to make a contourf plot just fine using hist. An example using data from a random, normal distribution:

import numpy as np
import matplotlib.pyplot as plt

n_points = 1000
x = np.random.normal(0, 2, n_points)
y = np.random.normal(0, 2, n_points)

hist, xedges, yedges = np.histogram2d(x, y, bins=np.sqrt(n_points))

fig2D = plt.figure()
ax2D = fig2D.add_subplot(111)
ax2D.contourf(hist, interpolation='nearest', 
              extent=(xedges[0], xedges[-1], yedges[0], yedges[-1]))
plt.show()

returns an image like this.

As for your second question, regarding a color-coded 3D bar plot, how about this (using the same data as above but with 1/10 the size):

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

n_points = 100
x = np.random.normal(0, 2, n_points)
y = np.random.normal(0, 2, n_points)

hist, xedges, yedges = np.histogram2d(x, y, bins=np.sqrt(n_points))

# Following your data reduction process
xpos, ypos = np.meshgrid(xedges[:-1], yedges[:-1])

length, width = 0.4, 0.4
xpos = xpos.flatten()
ypos = ypos.flatten()
zpos = np.zeros(n_points)
dx = np.ones(n_points) * length
dy = np.ones(n_points) * width
dz = hist.flatten()

# This is where the colorbar customization comes in
dz_normed = dz / dz.max()
normed_cbar = colors.Normalize(dz_normed.min(), dz_normed.max())
# Using jet, but should work with any colorbar
color = cm.jet(normed_cbar(dz_normed))

fig3D = plt.figure()
ax3D = fig3D.add_subplot(111, projection='3d')
ax3D.bar3d(xpos, ypos, zpos, dx, dy, dz, color=color)
plt.show()

I get this image.

like image 192
lanery Avatar answered Nov 14 '22 23:11

lanery