Jones Vectors
Scott Prahl
Feb 2026
[1]:
%config InlineBackend.figure_format = 'retina'
import sys
import numpy as np
import matplotlib.pyplot as plt
if sys.platform == "emscripten":
import micropip
await micropip.install("pypolar")
from pypolar import jones
from pypolar import visualization as vis
Introduction
This notebook generates Jones vectors for different polarization states and derives parameters from them. It shows that pypolar.jones produces results that match those from standard references.
Complete details of the assumptions can be found in Jupyter notebook on Conventions
Resources used or mentioned in this notebook.
Jones, “A New Calculus for the Treatment of Optical Systems”, JOSA, 38, 681 (1948).
Azzam, Ellipsometry and Polarized Light, 1977.
Collett, Field Guide to Polarization, 2005.
Fowles, Introduction to Modern Optics, 1975.
Goldstein, Polarized Light, 2003.
Kliger, Polarized Light in Optics and Spectroscopy, 1990
Shurcliff, Polarized Light Production and Use, 1962.
Tompkins, Handbook of Ellipsometry, 2005.
Comparison with Kliger Appendix A page 275
Here the Jones vectors (and polarization angles) are
[2]:
def printit(J):
alpha = np.degrees(jones.ellipse_azimuth(J))
tanomega = jones.ellipticity(J)
beta = np.degrees(jones.amplitude_ratio_angle(J))
delta = np.degrees(jones.phase(J))
print(
"%6.2f %6.3f %6.2f %7.2f [%13s, %13s]"
% (alpha, tanomega, beta, delta, J[0].__format__(".3f"), J[1].__format__(".3f"))
)
print("alpha tan(omega) beta ϕy-ϕx Standard Normalized")
light = jones.field_horizontal()
# print("Jones vector for horizontally-polarized light")
printit(light)
light = jones.field_vertical()
# print("Jones vector for vertically-polarized light")
printit(light)
light = jones.field_linear(np.radians(45))
# print("Jones vector for 45° linearly polarized light")
printit(light)
light = jones.field_linear(np.radians(-45))
# print("Jones vector for -45° linearly polarized light")
printit(light)
light = jones.field_linear(np.radians(30))
# print("Jones vector for 30° linearly polarized light")
printit(light)
light = jones.field_linear(np.radians(-60))
# print("Jones vector for -60° linearly polarized light")
printit(light)
light = jones.field_right_circular()
# print("Jones vector for right circularly polarized light")
printit(light)
light = jones.field_left_circular()
# print("Jones vector for left circularly polarized light")
printit(light)
J = 1 / np.sqrt(5) * np.array([2, 1j])
printit(J)
J = 1 / np.sqrt(5) * np.array([2, -1j])
printit(J)
J = 1 / np.sqrt(5) * np.array([1, 2j])
printit(J)
J = 1 / np.sqrt(5) * np.array([1, -2j])
printit(J)
J = 1 / 2 * np.array([np.sqrt(2), 1 + 1j])
printit(J)
J = 1 / 2 * np.array([np.sqrt(2), 1 - 1j])
printit(J)
J = 1 / 2 / np.sqrt(2) * np.array([np.sqrt(6), 1 + 1j])
printit(J)
J = np.sqrt(6) / 4 * np.array([2 / np.sqrt(6), -1 - 1j])
printit(J)
alpha tan(omega) beta ϕy-ϕx Standard Normalized
0.00 0.000 0.00 0.00 [ 1.000, 0.000]
90.00 0.000 90.00 0.00 [ 0.000, 1.000]
45.00 0.000 45.00 0.00 [ 0.707, 0.707]
-45.00 0.000 45.00 180.00 [ 0.707, -0.707]
30.00 0.000 30.00 0.00 [ 0.866, 0.500]
-60.00 0.000 60.00 180.00 [ 0.500, -0.866]
45.00 1.000 45.00 90.00 [ 0.707+0.000j, 0.000+0.707j]
45.00 -1.000 45.00 -90.00 [ 0.707+0.000j, 0.000-0.707j]
0.00 0.500 26.57 90.00 [ 0.894+0.000j, 0.000+0.447j]
0.00 -0.500 26.57 -90.00 [ 0.894+0.000j, 0.000-0.447j]
90.00 0.500 63.43 90.00 [ 0.447+0.000j, 0.000+0.894j]
90.00 -0.500 63.43 -90.00 [ 0.447+0.000j, 0.000-0.894j]
45.00 0.414 45.00 45.00 [ 0.707+0.000j, 0.500+0.500j]
45.00 -0.414 45.00 -45.00 [ 0.707+0.000j, 0.500-0.500j]
25.38 0.342 30.00 45.00 [ 0.866+0.000j, 0.354+0.354j]
-64.62 -0.342 60.00 -135.00 [ 0.500+0.000j, -0.612-0.612j]
Comparison with Shurcliff Table 2.1 page 23
[3]:
def printit(J):
alpha = np.degrees(jones.ellipse_azimuth(J))
tanomega = jones.ellipticity(J)
ratio = jones.amplitude_ratio(J)
delta = np.degrees(jones.phase(J))
print(
"%6.2f %6.3f %7.2f %7.2f [%13s, %13s]"
% (alpha, tanomega, ratio, delta, J[0].__format__(".3f"), J[1].__format__(".3f"))
)
print(" tilt b/a Eyo/Exo ϕy-ϕx Standard Normalized")
J = np.array([1, 0])
printit(J)
J = np.array([0, 1])
printit(J)
J = 1 / np.sqrt(2) * np.array([1, 1])
printit(J)
J = 1 / np.sqrt(2) * np.array([1, -1])
printit(J)
J = 1 / np.sqrt(2) * np.array([-1j, 1])
printit(J)
J = 1 / np.sqrt(2) * np.array([1j, 1])
printit(J)
J = 1 / np.sqrt(5) * np.array([-2j, 1])
printit(J)
J = 1 / np.sqrt(5) * np.array([-1j, 2])
printit(J)
J = 0.325 * np.array([2.73, 1 + 1j])
printit(J)
tilt b/a Eyo/Exo ϕy-ϕx Standard Normalized
0.00 0.000 0.00 0.00 [ 1.000, 0.000]
90.00 0.000 inf 0.00 [ 0.000, 1.000]
45.00 0.000 1.00 0.00 [ 0.707, 0.707]
-45.00 0.000 1.00 180.00 [ 0.707, -0.707]
45.00 1.000 1.00 90.00 [ 0.000-0.707j, 0.707+0.000j]
45.00 -1.000 1.00 -90.00 [ 0.000+0.707j, 0.707+0.000j]
0.00 0.500 0.50 90.00 [ 0.000-0.894j, 0.447+0.000j]
90.00 0.500 2.00 90.00 [ 0.000-0.447j, 0.894+0.000j]
22.52 0.318 0.52 45.00 [ 0.887+0.000j, 0.325+0.325j]
Comparison with Wikipedia or Fowles (page 34)
These treatments use \(e^{kz-\omega t}\) we need to use jones.use_alternate_convention(True) to account for this different convention.
[4]:
def printit(J):
alpha = np.degrees(jones.ellipse_azimuth(J))
tanomega = jones.ellipticity(J)
ratio = jones.amplitude_ratio(J)
delta = np.degrees(jones.phase(J))
print(
"%6.2f %6.3f %7.2f %7.2f [%13s, %13s]"
% (alpha, tanomega, ratio, delta, J[0].__format__(".3f"), J[1].__format__(".3f"))
)
# to account for different sign convention
jones.use_alternate_convention(True)
print(" tilt b/a Eyo/Exo ϕy-ϕx Standard Normalized")
light = jones.field_horizontal()
print("Jones vector for horizontally-polarized light")
printit(light)
light = jones.field_vertical()
print("Jones vector for vertically-polarized light")
printit(light)
light = jones.field_linear(np.radians(45))
print("Jones vector for 45° linearly polarized light")
printit(light)
light = jones.field_linear(np.radians(-45))
print("Jones vector for -45° linearly polarized light")
printit(light)
light = jones.field_right_circular()
print("Jones vector for right circularly polarized light")
printit(light)
light = jones.field_left_circular()
print("Jones vector for left circularly polarized light")
printit(light)
jones.use_alternate_convention(False)
tilt b/a Eyo/Exo ϕy-ϕx Standard Normalized
Jones vector for horizontally-polarized light
0.00 0.000 0.00 0.00 [ 1.000, 0.000]
Jones vector for vertically-polarized light
90.00 0.000 inf 0.00 [ 0.000, 1.000]
Jones vector for 45° linearly polarized light
45.00 0.000 1.00 0.00 [ 0.707, 0.707]
Jones vector for -45° linearly polarized light
-45.00 0.000 1.00 180.00 [ 0.707, -0.707]
Jones vector for right circularly polarized light
45.00 -1.000 1.00 -90.00 [ 0.707-0.000j, 0.000-0.707j]
Jones vector for left circularly polarized light
45.00 1.000 1.00 90.00 [ 0.707-0.000j, 0.000+0.707j]
Round tripping through code
This tests construction and deconstruction of Jones vectors.
[5]:
def testit(azimuth, ellipticity_angle, phi_x, E0):
J = jones.field_elliptical(azimuth, ellipticity_angle, phi_x, E0)
alpha = jones.ellipse_azimuth(J)
phix = np.angle(J[0])
epsilon = jones.ellipticity_angle(J)
delta = jones.phase(J)
Ex0, Ey0 = np.abs(J)
e0 = np.sqrt(Ex0**2 + Ey0**2)
print("%6.2f %6.2f " % (np.degrees(azimuth), np.degrees(alpha)), end="")
print("%6.2f %6.2f " % (np.degrees(ellipticity_angle), np.degrees(epsilon)), end="")
print("%6.2f %6.2f " % (np.degrees(phi_x), np.degrees(phix)), end="")
print("%6.2f %6.2f " % (E0, e0))
print("azimuth calc epsilon calc phi_x calc E0 calc")
ellipticity_angle = np.radians(12)
phi_x = np.radians(-17)
E0 = 3
for az in [-89, -30, -40, 0, 40]:
azimuth = np.radians(az)
testit(azimuth, ellipticity_angle, phi_x, E0)
print()
azimuth = np.radians(55)
E0 = 5
for p in [-89, -30, -40, 0, 40]:
phi_x = np.radians(p)
testit(azimuth, ellipticity_angle, phi_x, E0)
print()
azimuth = np.radians(-15)
phi_x = np.radians(17)
E0 = 0.5
for p in [-44, -30, 0, 15, 40]:
ellipticity_angle = np.radians(p)
testit(azimuth, ellipticity_angle, phi_x, E0)
azimuth calc epsilon calc phi_x calc E0 calc
-89.00 -89.00 12.00 12.00 -17.00 -17.00 3.00 3.00
-30.00 -30.00 12.00 12.00 -17.00 -17.00 3.00 3.00
-40.00 -40.00 12.00 12.00 -17.00 -17.00 3.00 3.00
0.00 0.00 12.00 12.00 -17.00 -17.00 3.00 3.00
40.00 40.00 12.00 12.00 -17.00 -17.00 3.00 3.00
55.00 55.00 12.00 12.00 -89.00 -89.00 5.00 5.00
55.00 55.00 12.00 12.00 -30.00 -30.00 5.00 5.00
55.00 55.00 12.00 12.00 -40.00 -40.00 5.00 5.00
55.00 55.00 12.00 12.00 0.00 -0.00 5.00 5.00
55.00 55.00 12.00 12.00 40.00 40.00 5.00 5.00
-15.00 -15.00 -44.00 -44.00 17.00 17.00 0.50 0.50
-15.00 -15.00 -30.00 -30.00 17.00 17.00 0.50 0.50
-15.00 -15.00 0.00 0.00 17.00 17.00 0.50 0.50
-15.00 -15.00 15.00 15.00 17.00 17.00 0.50 0.50
-15.00 -15.00 40.00 40.00 17.00 17.00 0.50 0.50
Intensities
[6]:
light = jones.field_horizontal()
inten = jones.intensity(light)
print("Intensity for horizontally-polarized light %.3f" % inten)
light = jones.field_vertical()
inten = jones.intensity(light)
print("Intensity for vertically-polarized light %.3f" % inten)
light = jones.field_linear(np.radians(45))
inten = jones.intensity(light)
print("Intensity for 45° linearly polarized light %.3f" % inten)
light = jones.field_right_circular()
inten = jones.intensity(light)
print("Intensity for right circularly polarized light %.3f" % inten)
light = jones.field_left_circular()
inten = jones.intensity(light)
print("Intensity for left circularly polarized light %.3f" % inten)
Intensity for horizontally-polarized light 1.000
Intensity for vertically-polarized light 1.000
Intensity for 45° linearly polarized light 1.000
Intensity for right circularly polarized light 1.000
Intensity for left circularly polarized light 1.000
The polarization variable \(\chi\)
The polarization variable is defined as
which happens to be equal to
where \(\alpha\) is the azimuth of the ellipse and \(\varepsilon=\tan{b/a}\) is the ellipticity angle (\(b\) and \(a\) are the minor and major axes of the ellipse.
[7]:
azimuth = np.radians(-15)
phi_x = np.radians(17)
E0 = 0.5
for p in [-44, -30, 0, 15, 40]:
ellipticity_angle = np.radians(p)
tane = np.tan(ellipticity_angle)
tana = np.tan(azimuth)
J = jones.field_elliptical(azimuth, ellipticity_angle, phi_x, E0)
chi1 = (tana + 1j * tane) / (1 - 1j * tana * tane)
print(f"jones = {jones.polarization_variable(J):.4f}")
print(f"expected = {chi1:.4f}")
print()
jones = -0.0169-0.9701j
expected = -0.0169-0.9701j
jones = -0.1745-0.6043j
expected = -0.1745-0.6043j
jones = -0.2679-0.0000j
expected = -0.2679+0.0000j
jones = -0.2474+0.2857j
expected = -0.2474+0.2857j
jones = -0.0755+0.8561j
expected = -0.0755+0.8561j
[ ]: