0

I would like to plot a 3D vector field on a 2D plane.

an example data i tried plotting but not able to get a 3D view of the vector fields

any help would be highly appreciated and thankful

tried plotting using matplotlib 3d but with no success

code-freeze
  • 465
  • 8
  • 8
  • What exactly do you mean when you say that you're plotting it "on a 2D plane"? – Ben Grossmann Jan 02 '23 at 18:18
  • the x variable remains constant. so basically i would like to plot these vectors in Y-Z plane. Thank you – code-freeze Jan 02 '23 at 18:23
  • Matplotlib can plot these points and arrows within 3D space (i.e. with x,y, and z axes), but I don't believe that there is a way to get matplotlib to apply a 3D effect to arrows over a 2D plane. – Ben Grossmann Jan 02 '23 at 18:28
  • okay. thank you so much. is there another plotting tool which can handle the vectors along with their magnitudes? – code-freeze Jan 02 '23 at 18:30
  • It's not clear what you mean by "handle the vectors" here. Are you still thinking of plotting a 3D arrow over a 2D plane? – Ben Grossmann Jan 02 '23 at 18:31
  • yes. i found this article https://mathematica.stackexchange.com/questions/110397/plotting-a-3d-vector-field-on-2d-plane which is similar to my requirement. i was curious if matplotlib can do something like this – code-freeze Jan 02 '23 at 18:44

1 Answers1

1

Here's a version inspired by this post that gives a much cleaner picture.

import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.patches import FancyArrowPatch
from mpl_toolkits.mplot3d import proj3d

class Arrow3D(FancyArrowPatch):
    def __init__(self, xs, ys, zs, *args, **kwargs):
        FancyArrowPatch.__init__(self, (0,0), (0,0), *args, **kwargs)
        self._verts3d = xs, ys, zs
        
    def do_3d_projection(self, renderer=None):
        xs3d, ys3d, zs3d = self._verts3d
        xs, ys, zs = proj3d.proj_transform(xs3d, ys3d, zs3d, self.axes.M)
        self.set_positions((xs[0],ys[0]),(xs[1],ys[1]))

        return np.min(zs)
        
coords_y = np.arange(-4,5)
coords_z = np.arange(-4,5)
coords = np.vstack([[0,y,z] for y in coords_y for z in coords_z])

angle = pi/4
R_mat = np.array([[cos(angle),-sin(angle)],[sin(angle),cos(angle)]])
vel_yz = coords[:,1:]@R_mat.T
vel = np.hstack([.1*np.ones([len(coords),1]),vel_yz])

fig,ax = plt.subplots(figsize = (10,10),subplot_kw = {"projection":"3d"})
ax.view_init(vertical_axis = 'x')
ax.plot3D(*coords.T, 'ro')

for p,v in zip(coords,.2*vel):
    a = Arrow3D(*zip(p,p+v), mutation_scale=20, 
                lw=2, arrowstyle="-|>", color="b")
    ax.add_artist(a)

Result:

enter image description here


Here's something that gets pretty close to what you're looking for, using that 3D quiver method and setting the x-axis to be the vertical axis.

I'm still looking into how we could get the arrows to look a little nicer.

import numpy as np
import matplotlib.pyplot as plt
from numpy.random import randn
from numpy import sin, cos, pi

coords_y = np.arange(-4,5)
coords_z = np.arange(-4,5)
coords = np.vstack([[0,y,z] for y in coords_y for z in coords_z])

R_mat = np.array([[cos(pi/4),-sin(pi/4)],[sin(pi/4),cos(pi/4)]])
vel_yz = coords[:,1:]@R_mat.T
vel = np.hstack([.1*np.ones([len(coords),1]),vel_yz])

fig,ax = plt.subplots(figsize = (10,10),subplot_kw = {"projection":"3d"})
ax.view_init(vertical_axis = 'x')
ax.plot3D(*coords.T, 'ro')
ax.quiver(*coords.T, *vel.T, length = .1)

Sample result:

enter image description here

Ben Grossmann
  • 4,387
  • 1
  • 12
  • 16
  • thank you so much. this looks reasonbly good except for the "not sharp" visualization. – code-freeze Jan 02 '23 at 19:00
  • @code-freeze You're welcome. I've changed the example vector field to something a bit more typical (i.e. continuously varying), and it looks better (but still not ideal). – Ben Grossmann Jan 02 '23 at 19:08
  • @code-freeze See my latest edit; we can get a much cleaner visualization – Ben Grossmann Jan 02 '23 at 19:33
  • i should say the latest image is so Amazing. Thank you so much for the help and your efforts. I hope i can re-use your code and modify it for my use. – code-freeze Jan 03 '23 at 08:11