I need plotting the circular histogram in matplotlib!
They should look like .
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np; np.random.seed(1)
r = np.ones(100)*0.9
phi = np.random.rand(100)*2.*np.pi
hist, xedges, yedges = np.histogram2d(r, phi, bins=25, range=[[0, 1.2], [0,2*np.pi*26./25]])
R,Phi = np.meshgrid(xedges[:-1], yedges[:-1])
X = R*np.cos(Phi)
Y = -R*np.sin(Phi)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
X[(R < 0.75) | (R > 1)] = np.nan
ax.plot_surface(X,Y, hist.T, alpha=0.2)
ax.plot_wireframe(X,Y, hist.T)
plt.show()
Output:
Related
I'm trying to plot a 2d histogram. The histogram is basically a galaxy and I have the points of each luminous point. I have plotted the histogram but it's not properly normalized, as the values of the colorbar should go from 0 to 1. How can I fix this?
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.stats import kde
fig, axes = plt.subplots(ncols=2, nrows=1, figsize=(20, 8))
data1 = pd.read_csv('mydata.txt', sep='\s+', header=None)
az1 = data1[0]
el1 = data1[1]
nbins = 250
hist1 = axes[0].hist2d(az1, el1, bins=nbins, cmap='magma', density=True)
fig.colorbar(hist1[3], ax = axes)
I tried with the function hist2Dbut I didn't find a way to normalized the result with it. So what I suggest is using the hitrogram from the numpy modul: np.nistogram2d where you can extract the result and then normalized the output before display it.
Here an example with random numbers:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.stats import kde
fig, axes = plt.subplots(ncols=2, nrows=1, figsize=(20, 8))
# data1 = pd.read_csv('mydata.txt', sep='\s+', header=None)
N=10000
az1 = np.random.random(N)
el1 = np.random.random(N)
nbins = 250
hist1 = axes[0].hist2d(az1, el1, bins=nbins, cmap='magma', density=True)
fig.colorbar(hist1[3], ax = axes)
H, xedges, yedges = np.histogram2d(el1, az1, bins=(nbins, nbins),density=True )
# H_normalized = H/float(az1.shape[0]) # the integral over the histogrm is 1
H_normalized = H/H.max((0,1)) # the max value of the histogrm is 1
extent = [xedges[0], xedges[-1], yedges[0], yedges[-1]]
im = axes[1].imshow(H_normalized, extent=extent, cmap='magma', interpolation='none',origin ='lower')
fig.colorbar(im, ax=axes[1])
plt.show()
I have computed a lot (~5000) of 3d points (x,y,z) in a quite complicated way so I have no function such that z = f(x,y). I can plot the 3d surface using
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
X = surface_points[:,0]
Y = surface_points[:,1]
Z = surface_points[:,2]
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
surf = ax.plot_trisurf(X, Y, Z, cmap=cm.coolwarm, vmin=np.nanmin(Z), vmax=np.nanmax(Z))
I would like to plot this also in 2d, with a colorbar indicating the z-value. I know there is a simple solution using ax.contour if my z is a matrix, but here I only have a vector.
Attaching the plot_trisurf result when rotated to xy-plane. This is what I what like to achieve without having to rotate a 3d plot. In this, my variable surface_points is an np.array with size 5024 x 3.
I had the same problems in one of my codes, I solved it this way:
import numpy as np
from scipy.interpolate import griddata
import matplotlib.pylab as plt
from matplotlib import cm
N = 10000
surface_points = np.random.rand(N,3)
X = surface_points[:,0]
Y = surface_points[:,1]
Z = surface_points[:,2]
nx = 10*int(np.sqrt(N))
xg = np.linspace(X.min(), X.max(), nx)
yg = np.linspace(Y.min(), Y.max(), nx)
xgrid, ygrid = np.meshgrid(xg, yg)
ctr_f = griddata((X, Y), Z, (xgrid, ygrid), method='linear')
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
ax.contourf(xgrid, ygrid, ctr_f, cmap=cm.coolwarm)
plt.show()
You could use a scatter plot to display a projection of your z color onto the x-y axis.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
N = 10000
surface_points = np.random.rand(N,3)
X = surface_points[:,0]
Y = surface_points[:,1]
Z = surface_points[:,2]
# fig = plt.figure()
# ax = fig.add_subplot(projection='3d')
# surf = ax.plot_trisurf(X, Y, Z, cmap=cm.coolwarm, vmin=np.nanmin(Z), vmax=np.nanmax(Z))
fig = plt.figure()
cmap = cm.get_cmap('coolwarm')
color = cmap(Z)[..., :3]
plt.scatter(X,Y,c=color)
plt.show()
Since you seem to have a 3D shape that is hollow, you could split the projection into two like if you cur the shape in two pieces.
fig = plt.figure()
plt.subplot(121)
plt.scatter(X[Z<0.5],Y[Z<0.5],c=color[Z<0.5])
plt.title('down part')
plt.subplot(122)
plt.scatter(X[Z>=0.5],Y[Z>=0.5],c=color[Z>+0.5])
plt.title('top part')
plt.show()
I wrote some code in juypter to visualize the Bivariate normal distribution. I want to modify the code so that I can visualize the contour plot(isodensity, say the x-y surface) at the same time. What should I add?
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import matplotlib as mpl
%matplotlib
if __name__ == '__main__':
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['axes.unicode_minus'] = False
d = np.random.randn(10000000, 2)
N = 30
density, edges = np.histogramdd(d, bins=[30, 30])
print("样本总数: ", np.sum(density))
density = density/density.max()
x = y = np.arange(N)
t = np.meshgrid(x,y)
fig = plt.figure()
ax = Axes3D(fig)
ax.scatter(t[0], t[1], density, c='r', s=15*density, marker='o', depthshade=True)
ax.plot_surface(t[0], t[1], density, cmap='rainbow', rstride=1, cstride=1, alpha=0.9, lw=1)
cset = ax.contourf(x, y, density,
zdir ='z',
offset = np.min(density),
)
ax.set_xlabel("x轴")
ax.set_ylabel("y轴")
ax.set_zlabel("z轴")
plt.title("二元高斯分布")
# plt.tight_layout(0.1)
plt.show()
import numpy as np
import matplotlib.pyplot as plt
# example data
x = np.arange(0.1, 4, 0.5)
y = np.exp(-x)
yerr = 0.1*np.random.rand(8)
fig, ax = plt.subplots()
ax.errorbar(x, y, linestyle='none', marker='*', yerr=yerr)
plt.show()
Hi, everyone! The goal is to add legend to the chart. y and yerr are labelled as 'mean' and 'std.Dev', respectively.
I want to plot a line in 3D Space and color regions of high curvature. Right now I have a workaround using a discrete scatter plot:
import matplotlib as mpl
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cmx
mpl.rcParams['legend.fontsize'] = 10
data = np.loadtxt('data',usecols=range(0,4))
x = data[:,0]
y = data[:,1]
z = data[:,2]
cs = data[:,3]
colorsMap='jet'
cm = plt.get_cmap(colorsMap)
cNorm = mpl.colors.Normalize(vmin=min(cs), vmax=max(cs))
scalarMap = cmx.ScalarMappable(norm=cNorm, cmap=cm)
fig = plt.figure()
scalarMap.set_array(cs)
fig.colorbar(scalarMap)
ax = fig.gca(projection='3d')
ax.scatter(x, y, z, c=scalarMap.to_rgba(cs), label='scatter curve')
ax.legend()
plt.show()
But I would rather have a continuous line plot.Is there a way to do that?
Depending on how many data points you have you might be able to get your way around this. For instance, consider the generated 3D spiral data below in substitution to your data.txt
import matplotlib as mpl
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cmx
mpl.rcParams['legend.fontsize'] = 10
theta = np.linspace(-4 * np.pi, 4 * np.pi, 1000)
z = np.linspace(-2, 2, 1000)
r = z**2 + 1
x = r * np.sin(theta)
y = r * np.cos(theta)
cs = 1/r
colorsMap='jet'
cm = plt.get_cmap(colorsMap)
cNorm = mpl.colors.Normalize(vmin=min(cs), vmax=max(cs))
scalarMap = cmx.ScalarMappable(norm=cNorm, cmap=cm)
fig = plt.figure()
scalarMap.set_array(cs)
ax = fig.gca(projection='3d')
ax.scatter(x, y, z, c=scalarMap.to_rgba(cs), marker='_', s=1)
plt.colorbar(scalarMap)
plt.show()
If the sampling frequency of your data points is not as "tight", then this won't look as nice. However, you could use this accepted answer to improve upon this.