I have this code that display a triangle filled with a gradient.
from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure()
ax = fig.gca(projection='3d')
X, Y = np.meshgrid(np.linspace(0,1), np.linspace(0,1))
Z = 1.-X-Y
Z[Z<0] = 0
cset = ax.contourf(X, Y, Z, zdir='x', levels=np.linspace(0,1),offset=0, cmap=plt.cm.jet)
ax.set_xlabel('X')
ax.set_xlim(0, 1)
ax.set_ylabel('Y')
ax.set_ylim(0,1)
ax.set_zlabel('Z')
ax.set_zlim(0,1)
plt.show()
How can I have the gradient "slices" in the other "direction"?
I mean, the gradient should look like this:
The answer to this question has already been given here:
Fill a triangle in 3D matplolib plot with a color gradient
where I show two ways of producing a gradient fill in a 3D triangle using contourf and plot_surface.
Related
I have a 3d plot with a colorbar and I would like the colorbar's size to scale with the size of the projection, no matter the orientation I select with ax.view_init.
It would also be great if I could get the aspect ratio of the 3d plot to be equal at the same time as well.
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
import matplotlib.colors
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.view_init(elev=90, azim=0)
x = np.arange(3)
X,Y = np.meshgrid(x,x)
Z = np.ones_like(X)
V = np.array([[3,2,2],[1,0,3],[2,1,0]])
norm = matplotlib.colors.Normalize(vmin=0, vmax=3)
ax.plot_surface(X, Y, Z, facecolors=plt.cm.jet(norm(V)), shade=False)
m = cm.ScalarMappable(cmap=plt.cm.jet, norm=norm)
m.set_array([])
plt.colorbar(m)
ax.set_xlabel('x')
ax.set_ylabel('y')
plt.show()
Example code stolen shamelessly from this question
I want to create a plot which looks similar to: https://www.shutterstock.com/de/image-vector/vector-abstract-3d-wave-wireframe-surrounding-445020520
I use something like the wire frame demo with a different background (best case a blue color gradient):
from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt
from matplotlib import cm
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d', axisbg='blue')
# Grab some test data, e.g.gcreate noisy sea surface data
X, Y, Z = axes3d.get_test_data(0.05)
# Plot a basic white wireframe for the surface
ax.plot_wireframe(X, Y, Z, rstride=10, cstride=10, color='white')
plt.show()
What would you take to make this more look like the example?
Cheers Bene
Here is one (out of many) options. Using a surface plot in the background of the wireframe can give the plot some shading and make it more look like the picture.
import numpy as np
from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d', facecolor='#1a5a98')
plt.subplots_adjust(0,0,1,1)
fig.patch.set_color('#1a5a98')
#Generate some data
x = np.linspace(0,500,501)/(9*np.pi)
X,Y = np.meshgrid(x,x)
f = lambda x,y: np.sin(x+y**0.2)*np.cos(y-x**0.4)
Z = f(X,Y)
# plot surface, for nice shading
ax.plot_surface(X, Y, Z, rstride=10, cstride=10)
# plot wireframe for white lines on top
ax.plot_wireframe(X, Y, Z, rstride=10, cstride=10, color='white', linewidth=0.5)
#set axis off
ax.axis("off")
ax.set_xlim(6.42,11.17)
ax.set_ylim(6.42,11.17)
ax.set_zlim(-6,6)
ax.view_init(elev=25, azim=-88)
plt.show()
I am producing plots of a spacecraft's trajectory at a specific point in its orbit.
I have a piece of code which produces a 3d line plot in 3dMatplotlib (a part of mycode and figure is shown here (I have drastically reduced the number of points within X,Y,Z to ~20 per array to make it easier to simply copy and paste as the principle is the same):
#
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.axes3d import Axes3D
from numpy import *
XdS=[14.54156005, 14.53922242, 14.53688586, 14.53454823, 14.5322106 , 14.52987297, 14.52753426, 14.52519555, 14.52285792, 14.52051922, 14.51818051, 14.51584073, 14.51350095, 14.51116117, 14.5088214 , 14.50648162, 14.50414076, 14.50179991, 14.49945906, 14.49711821]
YdS=[31.13035144, 31.12920087, 31.12805245, 31.12690188, 31.12575131, 31.12460073, 31.12345016, 31.12229745, 31.12114473, 31.11999201, 31.1188393 , 31.11768443, 31.11652957, 31.11537471, 31.11421984, 31.11306283, 31.11190582, 31.11074882, 31.10959181, 31.1084348]
ZdS=[3.94109446, 3.94060316, 3.94011186, 3.93962083, 3.93912926, 3.93863796, 3.93814639, 3.93765482, 3.93716325, 3.93667169, 3.93617985, 3.93568828, 3.93519618, 3.93470434, 3.9342125 , 3.9337204 , 3.93322829, 3.93273592, 3.93224382, 3.93175144]
fig=plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot(XdS,YdS,ZdS,c='black',linewidth=2)
ax.set_xlabel('XKSM (Saturn Radii)')
ax.set_ylabel('YKSM (Saturn Radii)')
ax.set_zlabel('ZKSM (Saturn Radii)')
plt.show()
#
What I want to do is be able to plot the 2d plots X vs Y, X vs Z, and Y vs Z on the edges/planes of this plot i.e. show what the 3d trajectory looks like looking at it in the 3 2d planes and display them at each axis of the current plot. (It isn’t actually as complicated as it might sound, as I already have the X,Y,Z, values for the trajectory). Here I found a similar example which achieves this, however utilising all 3d plot functions, available at: http://matplotlib.org/1.3.1/examples/mplot3d/contour3d_demo3.html : If you check out check out the link it will show the type of image i am trying to achieve.
from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt
from matplotlib import cm
fig = plt.figure()
ax = fig.gca(projection='3d')
X, Y, Z = axes3d.get_test_data(0.05)
ax.plot_surface(X, Y, Z, rstride=8, cstride=8, alpha=0.3)
cset = ax.contour(X, Y, Z, zdir='z', offset=-100, cmap=cm.coolwarm)
cset = ax.contour(X, Y, Z, zdir='x', offset=-40, cmap=cm.coolwarm)
cset = ax.contour(X, Y, Z, zdir='y', offset=40, cmap=cm.coolwarm)
ax.set_xlabel('X')
ax.set_xlim(-40, 40)
ax.set_ylabel('Y')
ax.set_ylim(-40, 40)
ax.set_zlabel('Z')
ax.set_zlim(-100, 100)
plt.show()
This is in theory exactly what I need, in the way it takes sort of a planar view of the 3d situation. However I cannot implement a 2d line plot on a 3d axis nor can I use the offset command in a 2d plot (getting the error: TypeError: There is no line property "offset").
Is there a 2d equivalent to the 3d “offset” command and Is it possible to plot the 2d values on the planes of the 3d plot as I desire? Also is there a way to plot 2d lines having initialised a 3d projection? Can anyone offer any ideas/point me in any direction in general to help me achieve this?
My sincere thanks in advance and apologies if any part of this post is out of order, this is my first one!
Try this:
xmin = min(XdS)
ymax = max(YdS)
zmin = min(ZdS)
length_of_array = len(XdS)
xmin_array = [xmin] * length_of_array
ymax_array = [ymax] * length_of_array
zmin_array = [zmin] * length_of_array
fig=plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot(XdS,YdS,ZdS,zdir='z', c='r')
ax.plot(XdS,YdS,zmin_array, zdir='z', c='g')
ax.plot(xmin_array, YdS, ZdS, 'y')
ax.plot(XdS,ymax_array,ZdS,'b')
ax.set_xlabel('XKSM (Saturn Radii)')
ax.set_ylabel('YKSM (Saturn Radii)')
ax.set_zlabel('ZKSM (Saturn Radii)')
plt.show()
I've had a look at matplotlib's examples of 3d plots, but none of these give me what I want to plot, something like:
The plot shows a series of measurements on the y-axis (N) and each measurement has an intensity spectrum (p/2hk_L), i.e. N is fixed for each line you see in the graph. What is the easiest function to use to plot data like this?
Here is a try:
import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
x = np.linspace(-50,50,100)
y = np.arange(25)
X,Y = np.meshgrid(x,y)
Z = np.zeros((len(y),len(x)))
for i in range(len(y)):
damp = (i/float(len(y)))**2
Z[i] = 5*damp*(1 - np.sqrt(np.abs(x/50)))
Z[i] += np.random.uniform(0,.1,len(Z[i]))
ax.plot_surface(X, Y, Z, rstride=1, cstride=1000, color='w', shade=False, lw=.5)
ax.set_zlim(0, 5)
ax.set_xlim(-51, 51)
ax.set_zlabel("Intensity")
ax.view_init(20,-120)
plt.show()
I am trying to plot function f(x,y)=(x+2)*y^2 with some iso level curves projected on x-y plane. The code I used is this:
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
from matplotlib.ticker import LinearLocator, FixedLocator, FormatStrFormatter
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import axes3d, Axes3D
import pylab as p
fig = plt.figure()
ax = Axes3D(fig)
X = np.arange(0, 2.5, 0.1)
Y = np.arange(0, 2.5, 0.1)
X, Y = np.meshgrid(X, Y)
Z = ((X+2))*(Y**2)
surf = ax.plot_surface(X, Y, Z,rstride=1, cstride=1, alpha=0.3, cmap=cm.jet)
cset=plt.contour(X,Y,Z,zdir='z',offset=0)
ax.clabel(cset, fontsize=9, inline=1)
ax.set_zlim3d(0, 30)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
fig.colorbar(surf, shrink=0.5, aspect=5)
plt.show()
My problem is that zdir doesn't work, that is the contour lines are on the surface and not on x-y plane.
Any ideas?
Thanks in advance
Your code works fine for me (matplotlib 1.0.1).
Btw: It seems that this example was added to gallery with matplotlib 1.0. Maybe this is a problem the previous version?
zdir defines the direction to project. (zdir='x' projects along the x axis) offset defines the location of the plane to be projected onto (along the axis defined by zdir)
Example
I'm going to guess what you want is:
cset=plt.contour(X,Y,Z,zdir='z',offset=30)
-> xs and ys: These are coordinates for x and y axes
-> zs: This is the value(s) for z axis. It can be one for all points or one for each point
--> zdir: This will choose what will be the z-axis dimension (usually this is zs, but can
be xs or ys)