Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Z has to be 2-dimensional for 3d plotting in matplotlib

I am trying to plot 3d Surface plots using code from this site using matplotlib:

X,Y and Z are obtained as below:

from math import pi
from numpy import cos, meshgrid
alpha = 0.7
phi_ext = 2 * pi * 0.5

def flux_qubit_potential(phi_m, phi_p):
    return 2 + alpha - 2 * cos(phi_p)*cos(phi_m) - alpha * cos(phi_ext - 2*phi_p)

phi_m = linspace(0, 2*pi, 100)
phi_p = linspace(0, 2*pi, 100)
X,Y = meshgrid(phi_p, phi_m)
Z = flux_qubit_potential(X, Y).T

And 3d plotting is done with following code:

from mpl_toolkits.mplot3d.axes3d import Axes3D

fig = plt.figure(figsize=(14,6))

# `ax` is a 3D-aware axis instance, because of the projection='3d' keyword argument to add_subplot
ax = fig.add_subplot(1, 2, 1, projection='3d')

p = ax.plot_surface(X, Y, Z, rstride=4, cstride=4, linewidth=0)

# surface_plot with color grading and color bar
ax = fig.add_subplot(1, 2, 2, projection='3d')
p = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm, linewidth=0, antialiased=False)
cb = fig.colorbar(p, shrink=0.5)

However, if I replace X,Y and Z by my x,y,z 3d data (sample give below), there is an error that Z has to be 2 dimensional. How can I plot with usual x,y,z values, as following:

   x   y   z
0  12  0  0.1
1  13  1  0.8
2  14  3  1.0
3  16  4  1.2
4  18  4  0.7
like image 803
rnso Avatar asked Nov 11 '18 08:11

rnso


People also ask

Is matplotlib 2D or 3D?

Matplotlib is an excellent 2D and 3D graphics library for generating scientific figures.

Are 3D graphs possible in matplotlib?

Matplotlib was introduced keeping in mind, only two-dimensional plotting. But at the time when the release of 1.0 occurred, the 3d utilities were developed upon the 2d and thus, we have 3d implementation of data available today! The 3d plots are enabled by importing the mplot3d toolkit.

What function would we use to plot a 3D surface in matplotlib?

Creating 3D surface Plot Surface plots are created by using ax. plot_surface() function.

How do I draw a 3D shape in matplotlib?

Matplotlib was introduced for two-dimensional plotting. The 3d plot is enabled by importing the mplot3d toolkit., which comes with your standard Matplotlib. After importing, 3D plots can be created by passing the keyword projection=”3d” to any of the regular axes creation functions in Matplotlib.


2 Answers

This is because, in my understanding, to draw a surface you need to form a polygon mesh. To draw a 3d surface, you need to have small squares, for example, on the xy-plane and then have 1 corresponding z value for all the x-y points. The smaller the area of the square means finer mesh-grid and better resolution(smooth-looking surface.) Now if you have an arbitrary set of xyz points, how matplotlib can determine which surface to draw. That is why a mesh is required. You can of course plot 3d scatter or line plots with your data.

like image 99
anotherone Avatar answered Oct 26 '22 22:10

anotherone


In the documentation you will find that x, y and z need to a 2D array. For the coordinates x and y you will need to use numpy.meshgrid as you show in the first piece of code. This creates a 2D array for each coordinate where x and y are constant along the other direction and vary on its own direction.

With respect to z, this also needs to be a 2D array since Axes3D.surface_plot maps each element of the 2D array z with the 2D grid defined by x and y.

Hence, when you use your own x, y and z make sure that you use numpy.meshgrid for x and y and, then, define z = f(x,y) (e.g. the function flux_qubit_potential you show).

Edit:

After OP's comment, is clear that the desired output is a plot where the function g is g = f(x,y,z). This would mean that g is a 3D array in the end. To do this in terms of iso-surfaces have a look at these answers.

like image 22
b-fg Avatar answered Oct 26 '22 22:10

b-fg