# How do I plot a plane EM wave?

I would like to display an electromagnetic (EM) wave. I have written code that works, but it does not "shade" the area between the graph and the axes. Both the Filling and EdgeForm commands are ignored.

strength = 2; frequency = 3;

wave1 = ParametricPlot3D[{t (x/6.28), -strength Sin[frequency t (x/6.28)], 0},
{t, 0, 2 Pi},
PlotStyle->Directive[Thickness[.007], Lighter[Red, .5], Filling -> Axis]];
wave2 = ParametricPlot3D[{t (x/6.28), 0, strength Sin[frequency t(x/6.28)]},
{t, 0, 2 Pi},
PlotStyle -> Directive[Thickness[.007], Lighter[Blue, .5], Filling -> Axis]];

Show[wave1, wave2, Graphics3D[EdgeForm[Pink], wave1],
Graphics3D[EdgeForm[LightBlue], wave2],
Axes->False, Boxed->False, PlotRange->All, ImageSize->{500, 400}]


I would like to accomplish filling the portion between the two sinusoidal waves and the direction of propagation of the wave with color.

Here's a variation of the plane wave rendering done in rm -rf's answer. Here, I use arrows instead of lines to indicate the wave's displacement from the axis:

waveDiagram[xm_, col_, k_] := Flatten[First[
Normal[Plot[Sin[x], {x, 0, xm}, Mesh -> Full,
Point[{x_, y_}] :>
If[Chop[Abs[y]] < 0.1, Point[{x, 0}], Arrow[{{x, 0}, {x, y}}]]]] /.
v_?VectorQ /; Length[v] == 2 :> Insert[v, 0, k]

Graphics3D[(* axes *)
Arrow[{{0, 0, 0}, {9 π/2, 0, 0}}]}, {Arrowheads[.01 {-1, 1}],
Arrow[{{0, 1, 0}, {0, -1, 0}}], Arrow[{{0, 0, 1}, {0, 0, -1}}]}},
waveDiagram[4 π, Darker[Blue], 2],
waveDiagram[4 π, Darker[Green], 3]},
Boxed -> False, BoxRatios -> {2, 1, 1}] As a variation, here's a depiction of the circular polarization of a plane wave:

Show[
(* circularly polarized wave *)
Normal[ParametricPlot3D[{t, -Sin[t], Cos[t]}, {t, 0, 4 π}, Mesh -> Full,
Point[{x_, y_, z_}] :>
If[Chop[Norm[{y, z}]] < 0.1, Point[{x, 0, 0}],
Arrow[{{x, 0, 0}, {x, y, z}}]],
(* axes *)
Graphics3D[{{Gray, {Arrowheads[.02], Arrow[{{0, 0, 0}, {9 π/2, 0, 0}}]},
{Arrowheads[.01 {-1, 1}], Arrow[{{0, 1, 0}, {0, -1, 0}}],
Arrow[{{0, 0, 1}, {0, 0, -1}}]}}}],
Axes -> None, Boxed -> False, BoxRatios -> {2, 1, 1}, PlotRange -> All] The common theme in both diagrams is the use of the Mesh option of the plotting functions, which generates Point[]s on the curve(s) at preset locations. From here, we replace each Point[] object generated with an Arrow[] whose head has the coordinates of the original Point[]; how the position of the tail is determined depends on the plot being done.

You've gotten answers to the specific problem you had, but here's another way of visualizing the EM wave. This is how I've always seen it depicted in my textbooks, and the advantage is that it prints neatly in black & white.

Module[{w1, w2, colors, plot, lines},
w1[x_] := {x, 0, Sin[x]};
w2[x_] := {x, Sin[x], 0};
colors = Darker /@ {Blue, Green};

{plot, lines} = ParametricPlot3D[{w1[x], w2[x]}, {x, 0, 4 \[Pi]},
Boxed -> False, AxesOrigin -> {0, 0, 0}, MaxRecursion -> 0,
PlotStyle -> {{Thick, Thick}, colors}\[Transpose],
EvaluationMonitor :> Sow[{Line[{w1[x], {x, 0, 0}}], Line[{w2[x], {x, 0, 0}}]}]
] // Reap;

Show[plot,
Graphics3D[Insert[Flatten[lines, 1], colors, 1]\[Transpose]],
ViewPoint -> {3.009, -1.348, 0.759}, ViewVertical -> {0.406, -0.398, 5.732}, Ticks -> None,
AspectRatio -> 0.75
]
] • Please see if my edit is okay (hope no visible colour fringing is present) – Szabolcs Feb 19 '12 at 15:08
• Oh that's sexy. +1 – Mr.Wizard Feb 19 '12 at 15:45

If you use a full period for x you can get by with this cheap hack:

x = 2 Pi;

wave1 = ParametricPlot3D[{t (x/6.28), -strength Sin[
frequency t (x/6.28)], 0}, {t, 0, 2 Pi},
PlotStyle ->
Directive[Thickness[.007], Lighter[Red, .5], Filling -> Axis]];
wave2 = ParametricPlot3D[{t (x/6.28), 0,
strength Sin[frequency t (x/6.28)]}, {t, 0, 2 Pi},
PlotStyle ->
Directive[Thickness[.007], Lighter[Blue, .5], Filling -> Axis]];


Adding /. Line -> Polygon

Show[wave1, wave2, Axes -> False, Boxed -> False, PlotRange -> All,
ImageSize -> {500, 400}] /. Line -> Polygon My take on the hatched shading version:

strength = 1; frequency = 3; x = 5;

pts1 =
Table[
{t (x/6.28), -strength Sin[frequency t (x/6.28)], 0},
{t, 0, 2 Pi, 0.03}
];

pts2 = {#, 0, -#2} & @@@ pts1;

Graphics3D[{
Thickness[0.007],
{Lighter@Red, Line[pts1]},
{Lighter@Blue, Line[pts2]},
Thickness[0.002],
Pink,
Line[ {#, # {1, 0, 1}}& /@ pts1[[;; ;; 3]] ],
RGBColor[0.7, 0.7, 1],
Line[ {#, # {1, 1, 0}}& /@ pts2[[;; ;; 3]] ]
}] My take on arrows a la J. M.'s answer:

Table[{t/3, -Sin[t], Cos[t]}, {t, 0, 4 Pi, 0.05}] //
Graphics3D[{
{Orange, Lighting -> "Neutral", Tube@#},
{RGBColor[0, .8, 1], Arrow@Tube[{{0, 0, 0}, 1.5 #}, 0.01] & /@
{{3, 0, 0}, {0, 1, 0}, {0, -1, 0}, {0, 0, 1}, {0, 0, -1}}},
Opacity[0.3],
Arrow[{# {1, 0, 0}, #}] & /@ #[[;; ;; 3]]
}, Boxed -> False] & You could do something like

strength = 2; frequency = 3; x = 5;

wave1 = ParametricPlot3D[{t (x/6.28), -s strength Sin[
frequency t (x/6.28)], 0}, {t, 0, 2 Pi}, {s, 0, 1},
Mesh -> None, PlotStyle -> Lighter[Red, .5]];
wave2 = ParametricPlot3D[{t (x/6.28), 0,
s strength Sin[frequency t (x/6.28)]}, {t, 0, 2 Pi}, {s, 0, 1},
Mesh -> None, PlotStyle -> Lighter[Blue, .5]];

Show[wave1, wave2, Axes -> False, Boxed -> False, PlotRange -> All,
ImageSize -> {500, 400}, Lighting -> "Neutral"] Note that you can also combine the two waves in one ParametricPlot3D:

waves = ParametricPlot3D[
{{t (x/6.28), -s strength Sin[frequency t (x/6.28)], 0},
{t (x/6.28), 0, s strength Sin[frequency t (x/6.28)]}},
{t, 0, 2 Pi}, {s, 0, 1},
Mesh -> None,
PlotStyle -> {Lighter[Red, .5], Lighter[Blue, .5]},
PlotPoints -> {50, 2},
Boxed -> False, Axes -> False, PlotRange -> All,
Lighting -> "Neutral"
]


To get a cleaner output I would recommend taking control of the polygons in your plot more explicitly. If you rely on ParametricPlot3D, that control is harder to achieve.

Here is a function that plots an integer number of wavelengths with an arrow indicating the propagation direction, and blue face color for the electric field (red for magnetic field).

plotWave[λ_, nλ_, aspect_: 1/5] :=
Module[{nStep = 40, amplitudes},
amplitudes =
Table[
{aspect λ nλ Sin[2 Pi z/λ], 0, z},
{z, 0, λ nλ, λ/nStep/2}
];
Graphics3D[
{
{Black, Thick,
Arrow[{{0, 0, 0}, {0, 0, λ nλ*1.08}}]},
{FaceForm[Red],
Polygon[Partition[amplitudes, nStep + 1, nStep]]}, {FaceForm[
Blue], Polygon[
Partition[amplitudes.RotationMatrix[Pi/2, {0, 0, 1}],
nStep + 1, nStep]]
}}]];
plotWave[1, 5] The first argument is the wavelength, the second argument the number of full wavelength to plot. An optional third argument can be given to specify what ratio of the longitudinal plot length should be assigned to the transverse amplitude.

The output looks pretty much the same as in the other answers, but I generate the wave from a discrete list of points at which the amplitude is calculated. It's important to do this symmetrically so that each half wave has a start and end point on the axis.

The trick then is to make a Polygon out of each half wave. To get the end points to lie on the axis, I partition the amplitude list (amplitudes) with the appropriate sub-list size (nStep +1). Since consecutive half waves share a point on the axis, I have to add an offset as the third argument in Partition.

Finally, I use the fact that Polygon can accept a list of lists, to make the first wave. The second wave is done the same way, except that a rotation matrix is first applied to the list amplitudes.

Edit

If you want other ideas for how to represent waves, you may want to take a look at my web page and the CDF called "PlaneWaveField.cdf" linked near the bottom of the section on 3D arrows.

• You can consider using this palette for effortless image uploading. I added an image to the post. – Szabolcs Feb 19 '12 at 15:28
• Thanks - but in this case I didn't think the image adds much info. – Jens Feb 19 '12 at 16:34