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$):
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, cmap=plt.cm.plasma,
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))
ax.set_xlabel('$x$')
ax.set_ylabel('$y$')
ax.set_xlim(-5,5)
ax.set_ylim(-5,5)
ax.set_aspect('equal')
plt.savefig('capacitor.png', dpi=DPI)
plt.show()
The electric field of a polarized disc (plates separated by $d=0.1$):
Share on Twitter Share on Facebook
Comments
Comments are pre-moderated. Please be patient and your comment will appear soon.
Baudouin DILLMANN 3 years, 8 months ago
Great job,
Link | Replyplease replace
ax = fig.add_subplot(facecolor='k')
by
ax = fig.add_subplot(111)
christian 3 years, 8 months ago
Thank you.
Link | ReplyIt 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
Tony Langtry 2 years, 5 months ago
Hi Christian,
Link | ReplyThank 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.
christian 2 years, 5 months ago
Hi Tony,
Link | ReplyI 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,
Christian
New Comment