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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With