Adding different shades to a 3D plot in Python and Matplotlib - python

I'm looking for a VERY simple way of changing the colour of my 3D plot to make it look more interesting.
Here is my code (had to delete most of it because said i had too much code in my post):
from numpy import *
from matplotlib.pyplot import *
from mpl_toolkits.mplot3d import Axes3D
from numpy import array
from matplotlib import pyplot
from math import sqrt
X, Y = np.mgrid[:9, :21]
fig = figure()
ax = fig.add_subplot(1,1,1, projection='3d')
ax.set_xlabel('Time')
ax.set_ylabel('Step')
ax.set_zlabel('Probability')
ax.plot_surface(X, Y, probs)
show()
Here is my graph:
Any help would really be appreciated!!
Ive tried using the http://matplotlib.org/mpl_toolkits/mplot3d to no avail

Related

Python Scatter plot not working with "None" points

Say I create three lists:
x=[1,2,3]
y=[4,5,6]
z=[1,None,4]
How can I scatter this and simply only include the points with numbers (i.e. exclude the "none" point). My code won't produce a scatter plot when I include these lists (however when I include a number instead of "None" it works):
from mpl_toolkits import mplot3d
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
%matplotlib notebook
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(x, y, z, c='r', marker='o')
plt.show()
You can do
import numpy as np
and replace your None with a np.nan. The points containing np.nan will not be plotted in your scatter plot. See this matplotlib doc for more information.
If you have long lists containing None, you can perform the conversion via
array_containing_nans = np.array(list_containing_nones, dtype=float)
you can use numpy.nan instead of None
import numpy as np
z=[1,None,4]
z_numpy = np.asarray(z, dtype=np.float32)
....
ax.scatter(x, y, z_numpy, c='r', marker='o')
You should use NaNs instead of None which is not the same thing. A NaN is a float.
Minimal example
import numpy as np
import matplotlib.pyplot as plt
x=[1,2,3]
y=[4,5,6]
z=[1,np.nan,4]
plt.scatter(x,y,z)
plt.show()

Mayavi - hide "diagonal" lines in wireframe

I've just started using mayavi and was wondering if there's a way to plot the wireframe representation of the surface that looks like the one I'm used from matplotlib 3d.
Minimal example:
# sphere example
import numpy as np
from mayavi import mlab
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
# azimut and polar angle
phi = np.linspace(0,2*np.pi,10)
theta = np.linspace(0,np.pi,10)
phi, theta = np.meshgrid(phi,theta)
# cartesian coordinates
x = np.cos(phi)*np.sin(theta)
y = np.sin(phi)*np.sin(theta)
z = np.cos(theta)
#plotting using matplotlib
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_wireframe(x,y,z)
#plotting using mayavi
mlab.mesh(x,y,z,representation='wireframe', color=(0,0,1))
As you can see the outputs differ: matplotlib prints the lines with constant phi resp theta. Mayavi however, also prints diagonal lines (highlighted in yellow) connecting those paths.
I prefer the matplotlib version. Is there a way to achieve the same wireframe with mayavi?
TIA
Use mlab.surface() instead of mlab.mesh()

3D scatter_plot across 3D surface_plot

With the following code I try to plot a single scatter point over a 3D surface plot. But it is not working. Have tried Axes3D.text(x, y, z, s, zdir=None, **kwargs) instead of Axes3D.scatter(xs, ys, zs=0, zdir='z', s=20, c=None, depthshade=True,*args, **kwargs) which works. So I am curious why scatter is not working. What am I doing wrong?
Code
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from matplotlib import cm
from pylab import figure
from mpl_toolkits.mplot3d import Axes3D
fig = figure(figsize=(30,30))
ax = Axes3D(fig)
x=160+np.linspace(-100,100,100)
y=245+np.linspace(-100,100,100)
X,Y=np.meshgrid(x.round(0),y.round(0))
print(threshold1)
Z=Y-X
ax.plot_surface(X,Y,Z,cmap=cm.coolwarm,linewidth=3)
ax.scatter(160,245,85,s=400,c="b")
ax.tick_params(labelsize=35,direction='out', length=6, width=2)
plt.show()
Figure

Matplotlib does not display interactive graph in Ipython

I am trying to plot a 3D scatter plot with matplotlib from IPython. I am able to make a plot when I use the inline magic command as follows
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
%matplotlib inline
y = np.arange(10)
x = np.arange(10)
z = np.arange(10)
plt.figure()
ax = plt.axes(projection='3d')
ax.scatter(x,y,z)
But because the plot is inline, it is not interactive and I can not rotate it to the viewing angle I want. When I replace the inline command with
%matplotlib
I get
<mpl_toolkits.mplot3d.art3d.Path3DCollection at 0x7fb80bf40358>
as output, but no window or graph appears. If I add
plt.show()
to the end of the script, nothing happens. How do I plot an interactive graph in IPython?
You may want to use pylab to get rid of most imports and all the namespaces:
%pylab
from mpl_toolkits.mplot3d import Axes3D
y = rand(100)
x = rand(100)
z = rand(100)
ax = subplot(projection='3d')
ax.scatter(x, y, z)
See https://plot.ly/ for interactive inline plots.

Python : How to plot 3d graphs using Python?

I am using matplotlib for doing this
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
fig = plt.figure()
ax = Axes3D(fig)
x = [6,3,6,9,12,24]
y = [3,5,78,12,23,56]
ax.plot(x, y, zs=0, zdir='z', label='zs=0, zdir=z')
plt.show()
Now this builds a graph that is horizontal in the 3d space. How do I make the graph vertical so that it faces the user?
What I want to do is build multiple such vertical graphs that are separated by some distance and are facing the user.
bp's answer might work fine, but there's a much simpler way.
Your current graph is 'flat' on the z-axis, which is why it's horizontal. You want it to be vertical, which means that you want it to be 'flat' on the y-axis. This involves the tiniest modification to your code:
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
fig = plt.figure()
ax = Axes3D(fig)
x = [6,3,6,9,12,24]
y = [3,5,78,12,23,56]
# put 0s on the y-axis, and put the y axis on the z-axis
ax.plot(xs=x, ys=[0]*len(x), zs=y, zdir='z', label='ys=0, zdir=z')
plt.show()
Then you can easily have multiple such graphs by using different values for the ys parameter (for example, ys=[2]*len(x) instead would put the graph slightly behind).
Mayavi, in particular the mlab module, provides powerful 3D plotting that will work on large and or complex data, and should be easy to use on numpy arrays.
You can set the view angle of the 3d plot with the view_init() function. The example below is for version 1.1 of matplotlib.
from mpl_toolkits.mplot3d import axes3d
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
x = [6,3,6,9,12,24]
y = [3,5,78,12,23,56]
ax.plot(x, y, zs=0, zdir='z', label='zs=0, zdir=z')
ax.view_init(90, -90)
plt.show()
According to the documentation you want to use the ax.plot_surface(x,y,z) method. More information and chart types here.
The following should work:
x = [1,2,3]
y = [4,5,6]
z = [7,8,9]
data = zip(x,y,z)
#map data on the plane
X, Y = numpy.meshgrid(arange(0, max(x), 1), arange(0, max(y), 1))
Z = numpy.zeros((len(Y), len(X)), 'Float32')
for x_,y_,z_ in data:
Z[x_, y_] = z_ #this should work, but only because x and y are integers
#and arange was done with a step of 1, starting from 0
fig = p.figure()
ax = p3.Axes3D(fig)
ax.plot_surface(X, Y, Z)

Categories

Resources