Labeling first and last data point in matplotlib 3D - python

I have plotted a set of data points in a 3D figure and I would like to label the first and last data point with a different color and label them by a legend. How do I do that?
The code I have used is
from mpl_toolkits.mplot3d import Axes3D
x = np.array([0,1,2,3])
y = np.array([0,1,2,3])
z = np.array([0,1,2,3])
fig = plt.figure()
ax = fig.add_subplot(111,projection='3d')
ax.plot(x,y,z,'o-',markersize=5)
plt.show()

You can redraw the first and last point on the plot and label them as you give them color.
from mpl_toolkits.mplot3d import Axes3D
x = np.array([0,1,2,3])
y = np.array([0,1,2,3])
z = np.array([0,1,2,3])
fig = plt.figure()
ax = fig.add_subplot(111,projection='3d')
ax.plot(x[:1], y[:1], z[:1], 'o-',c='green', label="first", zorder=2)
ax.plot(x[-1:], y[-1:], z[-1:], 'o-',c='coral', label="last", zorder=2)
ax.plot(x,y,z,'o-',markersize=5, zorder=1)
ax.legend()
plt.show()
Output:

Related

Bothering frame on matplotlib 3D plots

I make 3d plots with matplotlib and I always get a weird frame with a normalized scale around my plot. Where does it come from and how can I get rid of it ?
Here is an example code that drives me to the problem :
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D
x = np.linspace(0,10)
y = np.linspace(0,10)
z = np.linspace(0,10)
# ------------- Figure ---------------
fig, ax = plt.subplots(figsize = (9,6))
ax = fig.gca(projection='3d')
ax.plot(np.sin(x), np.cos(y), z)
plt.show()
And here is the result :
I use plt.subplots() because I want a figure with a 3D and a 2D plot side by side.
You call plt.subplots(...) and this, of course, instantiates an Axes, complete of horizontal and vertical spines, before Matplotlib is informed that you want a 3D enabled Axes.
When you later call plt.gca(...) it's too late…
Simply use
fig, ax = plt.subplots(figsize = (9,6), subplot_kw={"projection" : "3d"})
or
fig = plt.figure(figsize = (9,6))
ax = fig.add_subplot(111, projection='3d')
Addressing OP's comment
Figure.add_subplot is pretty flexible…
fig = plt.figure()
fig.add_subplot(1,5,(1,4), projection='3d')
fig.add_subplot(1,5,5)
fig.tight_layout()
plt.show()

How do you plot vertical 3D planes?

see picture
Hey, I want to plot a function in 3d matplotlib python. The functions I want to plot are x = i where i stretches from 0 to 1 with increments of 0.20. So basically 4 vertical planes just as in the picture I shared.
You can create the planes as surface plots.
Here's an example:
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
X, Y = np.meshgrid(np.arange(-6, 6), np.arange(-6, 6))
Z = 0*X
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(X, Y, Z, alpha=0.5) # the horizontal plane
ax.plot_surface(Z, Y, X, alpha=0.5) # the vertical plane

How to do a 3D plot of gaussian using numpy?

I'm trying to plot a gaussian function using numpy.
the funtion is z=exp(-(x2+y2)/10) but I only get a 2D function
import numpy as np
from matplotlib import pyplot as plt
x=np.linspace(-10,10, num=100)
y=np.linspace(-10,10, num=100)
z=np.exp(-0.1*x**2-0.1*y**2)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_wireframe(x,y,z)
I obtain:
but I want to obtain:
I'm using numpy becouse I need the set of data.
You need to obtain the correct dimensions. This can be done using meshgrid. Also, your desired plot is a surface plot, not a wireframe (though you can do that too).
# import for colormaps
from matplotlib import cm
x=np.linspace(-10,10, num=100)
y=np.linspace(-10,10, num=100)
x, y = np.meshgrid(x, y)
z = np.exp(-0.1*x**2-0.1*y**2)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(x,y,z, cmap=cm.jet)
plt.show()
given the original formula of a gaussian distribution I wrote the following code:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D # <--- This is important for 3d plotting
A = 1
x0 = 0
y0 = 0
sigma_X = 2
sigma_Y = 2
xg = np.linspace(-5,5,num=100)
yg = np.linspace(-5,5,num=100)
theta= np.pi
X, Y = np.meshgrid(xg,yg)
a = np.cos(theta)**2/(2*sigma_X**2) + np.sin(theta)**2/(2*sigma_Y**2);
b = -np.sin(2*theta)/(4*sigma_X**2) + np.sin(2*theta)/(4*sigma_Y**2);
c = np.sin(theta)**2/(2*sigma_X**2) + np.cos(theta)**2/(2*sigma_Y**2);
aXXdet = np.array([a*(Xi-x0)**2 for Xi in X],float)
bbXYdet = np.array([2*b*(Xi-x0)*(Y[ii]-y0) for ii,Xi in enumerate(X)],float)
cYYdet = np.array([c*(Yi-y0)**2 for Yi in Y],float)
Z = np.array([A*np.exp( - (ai + bbXYdet[i] + cYYdet[i])) for i,ai in enumerate(aXXdet)],float);
# plot
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(X, Y, Z, cmap=cm.coolwarm)
ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
ax.set_zlabel('Z Label')
plt.show()
which also plots the distribution. So you could play around with the parameters and see their effect!

Defining colors of Matplotlib 3D bar plot

I can't figure out the right way to set a cmap (or colors) for a 3d bar plot in matplotlib in my iPython notebook. I can setup my chart correctly (28 x 7 labels) in the X and Y plane, with some random Z values. The graph is hard to interpret, and one reason is that the default colors for the x_data labels [1,2,3,4,5] are all the same.
Here is the code:
%matplotlib inline
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as npfig = plt.figure(figsize=(18,12))
ax = fig.add_subplot(111, projection='3d')
x_data, y_data = np.meshgrid(np.arange(5),np.arange(3))
z_data = np.random.rand(3,5).flatten()
ax.bar3d(x_data.flatten(),
y_data.flatten(),np.zeros(len(z_data)),1,1,z_data,alpha=0.10)
Which produces the following chart:
I don't want to define the colors manually for the labels x_data. How can I set up different 'random' cmap colors for each of the labels in x_data, still keeping the
ax.bar3d
parameter? Below is a variation using
ax.bar
and different colors, but what I need is ax.bar3d.
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure(figsize=(18,12))
ax = fig.add_subplot(111, projection='3d')
x_data, y_data = np.meshgrid(np.arange(5),np.arange(3))
z_data = np.random.rand(3,5)
colors = ['r','g','b'] # colors for every line of y
# plot colored 3d bars
for i in xrange(3): # cycle though y
# I multiply one color by len of x (it is 5) to set one color for y line
ax.bar3d(x_data[i], y_data[i], z_data[i], 1, 1, z_data[i], alpha=0.1, color=colors[i]*5)
# or use random colors
# ax.bar3d(x_data[i], y_data[i], z_data[i], 1, 1, z_data[i], alpha=0.1, color=[np.random.rand(3,1),]*5)
plt.show()
Result:

Matplotlib - Plot 3D with for loop

I want to plot several 3D points with matplotlib. My coordinates are stored in 2D arrays because i got multiple cases and so i would like to plot all the cases in a same 3D plot with a "for loop" but when i do that, the results appeared on different plots...
As example :
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
X = np.array([[3,2,1],[4,5,6]])
Y = np.array([[1,2,1],[2,3,4]])
Z = np.array([[10,11,12],[13,12,16]])
for i in range(0,X.shape[0]):
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(X[i,:], Y[i,:], Z[i,:], c='r', marker='o')
ax.set_xlabel('Z')
ax.set_ylabel('X')
ax.set_zlabel('Y')
plt.show()
You create a new figure each iteration and plot it each iteration. Also you always create the first suplot of a 1x1 subplot-grid.
You probably want a x.shape[0] x 1 grid or 1 x x.shape[0] grid:
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
X = np.array([[3,2,1],[4,5,6]])
Y = np.array([[1,2,1],[2,3,4]])
Z = np.array([[10,11,12],[13,12,16]])
# Create figure outside the loop
fig = plt.figure()
for i in range(0,X.shape[0]):
# Add the i+1 subplot of the x.shape[0] x 1 grid
ax = fig.add_subplot(X.shape[0], 1, i+1, projection='3d')
ax.scatter(X[i,:], Y[i,:], Z[i,:], c='r', marker='o')
ax.set_xlabel('Z')
ax.set_ylabel('X')
ax.set_zlabel('Y')
# Show it outside the loop
plt.show()
EDIT:
If you want to plot them all into the same plot use:
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1, projection='3d')
ax.set_xlabel('Z')
ax.set_ylabel('X')
ax.set_zlabel('Y')
for i in range(0,X.shape[0]):
# Only do the scatter inside the loop
ax.scatter(X[i,:], Y[i,:], Z[i,:], c='r', marker='o')
plt.show()

Categories

Resources