Chris Parmer — home

The electric dipole field

Coulomb's law, drawn as a direction field

Example from a field guide to quiver · shared helpers

The electric dipole field — Coulomb's law, drawn as a direction field

Python Code

"""The electric dipole field — Coulomb's law, drawn as a direction field."""
from pathlib import Path

from _shared import save, themed_layout, GREY_VIOLET_SCALE, PINK, TEAL

import numpy as np

CHART_NUM = 5

Q = [(-0.8, 0.0, +1.0), (0.8, 0.0, -1.0)]  # (x, y, charge)


def generate():
    xs = np.linspace(-2.2, 2.2, 27)
    ys = np.linspace(-1.8, 1.8, 23)
    X, Y = [a.ravel() for a in np.meshgrid(xs, ys)]

    Ex = np.zeros_like(X)
    Ey = np.zeros_like(Y)
    near = np.zeros_like(X, dtype=bool)
    for qx, qy, q in Q:
        dx, dy = X - qx, Y - qy
        r2 = dx * dx + dy * dy
        r = np.sqrt(r2)
        near |= r < 0.28          # hide arrows sitting on top of a charge
        Ex += q * dx / (r2 * r)
        Ey += q * dy / (r2 * r)

    mag = np.hypot(Ex, Ey)
    keep = ~near
    X, Y, Ex, Ey, mag = X[keep], Y[keep], Ex[keep], Ey[keep], mag[keep]

    # Direction field: every arrow unit length, color carries the magnitude.
    arrows = {
        "type": "quiver",
        "x": X.tolist(),
        "y": Y.tolist(),
        "u": (Ex / mag).tolist(),
        "v": (Ey / mag).tolist(),
        "arrowref": "paper",
        "lengthmode": "scaled",
        "lengthfactor": 0.95,
        "anchor": "center",
        "marker": {
            "color": np.log10(mag).tolist(),
            "colorscale": GREY_VIOLET_SCALE,
            "showscale": True,
            "colorbar": {"title": {"text": "log₁₀|E|"}, "thickness": 12, "len": 0.7},
            "line": {"width": 1.6},
        },
        "customdata": [f"|E| = {m:.2f}" for m in mag],
        "hovertemplate": "%{customdata}<extra></extra>",
        "showlegend": False,
    }
    charges = {
        "type": "scatter",
        "x": [q[0] for q in Q],
        "y": [q[1] for q in Q],
        "mode": "markers+text",
        "marker": {"size": 30, "color": [PINK, TEAL]},
        "text": ["+", "−"],
        "textfont": {"color": "#ffffff", "size": 18},
        "textposition": "middle center",
        "hoverinfo": "skip",
        "showlegend": False,
    }

    layout = themed_layout(
        xaxis={"showgrid": False, "zeroline": False, "visible": False},
        yaxis={"showgrid": False, "zeroline": False, "visible": False,
               "scaleanchor": "x"},
    )
    save(CHART_NUM, {"data": [arrows, charges], "layout": layout})

Made with Plotly