This is a read only copy of the old FEniCS QA forum. Please visit the new QA forum to ask questions

Plot line of constant x[0] for vector function

+1 vote

Hi, I have a surface described by a vector function, and I'd like to plot a line of constant x[0]. Here's a minimal example of the code.

from dolfin import *
import numpy as np
mesh = CircleMesh(Point(0.0,0.0),1.0,0.1)
space = VectorFunctionSpace(mesh,"CG",2,dim=3)
X = Function(space)
X.interpolate(Expression(("x[0]","x[1]","x[0]*x[0]+x[1]*x[1]")))
x_coords = []
y_coords = []
z_coords = []
for x in np.linspace(-0.9,0.9,10):
    p=Point(x,0.0)
    x_coords.append(X(p)[0])
    y_coords.append(X(p)[1])
    z_coords.append(X(p)[2])

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot(x_coords,y_coords,z_coords)
plt.show()

I am obviously doing something wrong, as this produces complete nonsense.

Any help would be appreciated.

asked Mar 6, 2014 by christopher.laing FEniCS Novice (290 points)

1 Answer

+2 votes

Hi, since your y values are all of order 1E-16 or so, matplotlib adjusted the y-axis accordingly and on that scale the curve is not smooth because e.g. points with y equal to 1E-16 and 9E-16 (which is 0) take you from one end of axis to another. So the fix is

plt.ylim([-1, 1])

Btw, why is it necessary represent the surface as vector map: x, y --> x, y, z? You know what x, y are so a scalar map: x, y --> z seems to be a more appropriate choice. The code would then look as follows (note that it does not need ylim adjustment)

from dolfin import *
import numpy as np

mesh = CircleMesh(Point(0.0,0.0), 1.0, 0.1)
space = FunctionSpace(mesh, "CG", 2)
X = Function(space)
X.interpolate(Expression("x[0]*x[0]+x[1]*x[1]"))

plot(X, interactive=True)

x_coords = np.linspace(-0.9, 0.9, 10)
y_coords = np.zeros(len(x_coords))
z_coords = np.zeros(len(x_coords))

for i, (x, y) in enumerate(zip(x_coords, y_coords)):
  z_coords[i] = X(x, y)

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot(x_coords, y_coords, z_coords)
plt.show() 
answered Mar 6, 2014 by MiroK FEniCS Expert (80,920 points)

Ah, well that is embarrassing. Thank you for your response.

Btw, why is it necessary represent the surface as vector map: x, y -->
x, y, z? You know what x, y are so a scalar map: x, y --> z seems to
be a more appropriate choice.

The actual equation I will be solving is an embedding of a Riemannian manifold, so that X is a map from an open subset of R^2 into R^3 :-)

Okay, thanks for clarification.

...