The electric field of a capacitor


Just a quick update on this blog post on visualizing the electric field of a multipole arrangement of electric charges to visualize the electric field of a capacitor (two oppositely-charged plates, separated by a distance $d$). The code, which uses Matplotlib's streamplot function to visualize the electric field from the plates, modelled as rows of discrete point charges, is below.

The electric field of a capacitor (plates separated by $d=2$): The electric field of a capacitor

import sys
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Circle

WIDTH, HEIGHT, DPI = 700, 700, 100

def E(q, r0, x, y):
    """Return the electric field vector E=(Ex,Ey) due to charge q at r0."""
    den = ((x-r0[0])**2 + (y-r0[1])**2)**1.5
    return q * (x - r0[0]) / den, q * (y - r0[1]) / den

# Grid of x, y points
nx, ny = 128, 128
x = np.linspace(-5, 5, nx)
y = np.linspace(-5, 5, ny)
X, Y = np.meshgrid(x, y)

# Create a capacitor, represented by two rows of nq opposite charges separated
# by distance d. If d is very small (e.g. 0.1), this looks like a polarized
# disc.
nq, d = 20, 2
charges = []
for i in range(nq):
    charges.append((1, (i/(nq-1)*2-1, -d/2)))
    charges.append((-1, (i/(nq-1)*2-1, d/2)))

# Electric field vector, E=(Ex, Ey), as separate components
Ex, Ey = np.zeros((ny, nx)), np.zeros((ny, nx))
for charge in charges:
    ex, ey = E(*charge, x=X, y=Y)
    Ex += ex
    Ey += ey

fig = plt.figure(figsize=(WIDTH/DPI, HEIGHT/DPI), facecolor='k')
ax = fig.add_subplot(facecolor='k')
fig.subplots_adjust(left=0, right=1, bottom=0, top=1)

# Plot the streamlines with an appropriate colormap and arrow style
color = np.log(np.sqrt(Ex**2 + Ey**2))
ax.streamplot(x, y, Ex, Ey, color=color, linewidth=1,,
              density=3, arrowstyle='->')

# Add filled circles for the charges themselves
charge_colors = {True: '#aa0000', False: '#0000aa'}
for q, pos in charges:
    ax.add_artist(Circle(pos, 0.05, color=charge_colors[q>0], zorder=10))

plt.savefig('capacitor.png', dpi=DPI)

The electric field of a polarized disc (plates separated by $d=0.1$): The electric field of a polarized disc

Current rating: 3.8


Comments are pre-moderated. Please be patient and your comment will appear soon.

Baudouin DILLMANN 3 years, 4 months ago

Great job,

please replace

ax = fig.add_subplot(facecolor='k')
ax = fig.add_subplot(111)

Link | Reply
Current rating: 3.5

christian 3 years, 4 months ago

Thank you.

It shouldn't be necessary to specify 111 for the add_subplot function (this is the default), but I did want the background colour of the Axes to be black. If the code is not working for you, you might need to upgrade your version of Matplotlib.
Cheers, Christian

Link | Reply
Current rating: 3

Tony Langtry 2 years, 1 month ago

Hi Christian,
Thank you for this lovely program and your excellent book! I am a beginner in Python, and trying to understand how this works. I am a little confused by this line:
ex, ey = E(*charge, x=X, y=Y)
...particularly the x=X, y=Y part. As I (mis)understood it, X and Y are arrays, but x and y are single numbers for the function E to calculate with. Can you explain what happens inside this loop and the function?
I would like to adapt this to calculate the magnetic field due to filament loops, and it should work very nicely if I can understand it properly.

Link | Reply
Current rating: 5

christian 2 years, 1 month ago

Hi Tony,
I think you have it – the function E takes a charge q and a position r0, and coordinates x and y, and then calculates the electric field, E, due to q at the location (x,y). If x and y are single numbers this is just a single vector, (Ex, Ey), but if they are arrays (e.g. passed as x=X, y=Y), then NumPy *vectorizes* all the operations in the function and returns the values of (Ex, Ey) for all values of x, y in X, Y.

I hope that makes sense,

Link | Reply
Current rating: 5

New Comment


required (not published)