0

I am trying to plot something like in this figure, but without success.

enter image description here

This is probably a 3d plot of a normal distribution. Can anybody help me with how to get such a plot? Here is my code which I am trying.

fig=plt.figure(figsize=(10,6))
ax=plt.axes(projection='3d')
x=np.arange(0,251,0.85)
y=np.arange(0,12,0.85)
X,Y=np.meshgrid(x,y)
for i in range(X.shape[0]):
    pos=np.empty(X.shape)
    R=(pos-0.85)/0.029
    Z=(1/0.29*np.sqrt(2*np.pi))*np.exp(-.5*R**2) #normal distribution
    ax.plot_surface(X,Y,Z) 
Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158
Kumar Hemjeet
  • 61
  • 1
  • 3
  • 9
  • Why do you think its a normal distribution while the label indicates a uniform distribution? What about a kde plot with an extreme low bandwidth? If I understand correctly you just want a plot but don't even have data? – JohanC May 15 '21 at 16:23
  • the data is i have been given lenght and breadth of rectangle .as you can see on plot and i will be given mean and std deviation of data and i need to plot like the mentioned figure. you can assume any percentage of mesh to be occupied for plotting. – Kumar Hemjeet May 15 '21 at 17:46
  • You can consider for normal distribution too.. as i have both normal and uniform distribution. You can assume any value of mean and std. deviation for the plot. – Kumar Hemjeet May 15 '21 at 17:59
  • Well, the image looks like the kde plot of a random uniform distribution inside some rectangle. It really doesn't look like a uniform distribution. The coordinates of the rectangle are merely some conditions, these are not really "data" – JohanC May 15 '21 at 20:23

1 Answers1

1

Here is an idea to create a plot that looks a bit similar. Starting from 300 random centers, a kde kernel is calculated with a very small bandwidth. The gaussian_kde function places gaussian bell shapes over each of the random centers and sums them.

The following code is a bit slow, because the surface is calculated and plotted over 200x200 positions. For scaling down the z-axis, the code from this post is borrowed.

import matplotlib.pyplot as plt
from scipy.stats import gaussian_kde
import numpy as np

x = np.linspace(0, 251, 200)
y = np.linspace(0, 12, 200)
centers_x = np.random.uniform(x[0], x[-1], 300)
centers_y = np.random.uniform(y[0], y[-1], 300)
centers = np.vstack([centers_x, centers_y])
kernel = gaussian_kde(centers, bw_method=0.09)

X, Y = np.meshgrid(x, y)
positions = np.vstack([X.ravel(), Y.ravel()])
Z = np.reshape(kernel(positions).T, X.shape)

fig = plt.figure(figsize=(10, 6))
ax = plt.axes(projection='3d')
surf = ax.plot_surface(X, Y, Z, cmap="hot", linewidth=0, rcount=200, ccount=200)
ax.get_proj = lambda: np.dot(Axes3D.get_proj(ax), np.diag([1, 1, 0.1, 1]))
ax.set_zticks([])
plt.show()

surface plot of 2d kde

JohanC
  • 71,591
  • 8
  • 33
  • 66
  • Thank you sir. I want to see z labels but the values are so close and it's nearly unreadable. How can i overcome this ? – Kumar Hemjeet May 16 '21 at 03:11
  • One way is to remove `set_zticks([])` and add `ax.zaxis.set_major_locator(matplotlib.tickerMaxNLocator(2))`. Another is to remove the scaling (`ax.get_proj = lambda: ....`) and add `ax.set_zlim(Z.max()*4)` (to still have a flattish looking surface). – JohanC May 16 '21 at 10:57
  • module 'matplotlib' has no attribute 'tickerMaxNLocator' – Kumar Hemjeet May 16 '21 at 13:56
  • Oops. Missing a dot. `matplotlib.ticker.MaxNLocator(2)` – JohanC May 16 '21 at 14:27