An interactive 2D electric field and equipotential visualizer built with Python, NumPy, and Matplotlib. Click to place positive and negative charges and see the resulting electric field lines and equipotential surfaces in real-time.
Example visualization showing field lines (black arrows) originating from positive charges and terminating at negative charges, with equipotential lines (purple contours) surrounding them.
- Interactive charge placement: Click anywhere on the plot to add point charges
- Real-time visualization: Electric field lines and equipotential surfaces update instantly
- Toggle charge type: Switch between positive and negative charges using radio buttons
- Color-coded display:
- Blue circles with
+symbols for positive charges - Red circles with
−symbols for negative charges - Black arrows showing electric field direction
- Purple contour lines for equipotential surfaces
- Blue circles with
- Physics-accurate: Based on Coulomb's Law and the gradient relationship between field and potential
The electric potential at any point is the sum of contributions from all charges:
Where:
-
$V$ = electric potential (volts) -
$k$ = Coulomb's constant (set to 1 for simplicity) -
$q_i$ = magnitude of charge$i$ -
$r_i$ = distance from charge$i$ to the point
The electric field is derived from the potential gradient:
Electric field lines are always perpendicular to equipotential lines. This fundamental relationship arises because the field points in the direction of steepest potential decrease.
- Python 3.7 or higher
- pip (Python package manager)
- Clone the repository:
git clone https://github.com/dn-stef/electric_field_mapper.git
cd electric_field_mapper- Install required packages:
pip install numpy matplotlibOr using requirements.txt:
pip install -r requirements.txtRun the simulator:
python main.py- Select charge type: Use the radio buttons on the left to choose "Positive" or "Negative"
- Place charges: Click anywhere on the plot to add a charge
- Observe: Watch the electric field lines (black arrows) and equipotential contours (purple lines) update in real-time
- Start with a single charge to see the radial field pattern
- Place opposite charges to see field lines connecting them
- Place same-sign charges to see how fields repel and combine
- Equipotential lines show regions of equal voltage (like topographic elevation lines)
electric_field_mapper/
│
├── main.py # Entry point - initializes and runs the application
├── charges.py # Charge and ChargeManager classes
├── field_calculator.py # Physics calculations (potential, E-field)
├── visualizer.py # Matplotlib plotting and rendering
├── interactive_handler.py # Mouse clicks, button callbacks, event handling
├── .gitignore # Git ignore file
├── README.md # This file
└── images # Example visualization used in this README
-
charges.py: Defines theChargeclass (stores position and magnitude) andChargeManagerclass (manages the collection of charges and current placement mode) -
field_calculator.py: Contains pure physics calculations:create_grid(): Generates the 2D coordinate gridcalculate_potential(): Computes electric potential at all grid pointscalculate_electric_field(): Derives field from potential using gradient
-
visualizer.py: Handles all matplotlib visualization:- Draws streamplot for field lines
- Draws contour plot for equipotentials
- Renders charge markers with +/− symbols
- Creates radio button UI controls
-
interactive_handler.py: Connects user interactions to physics:- Handles mouse clicks to place charges
- Manages mode switching (positive/negative)
- Triggers recalculation and redrawing
-
main.py: Ties everything together and launches the application
-
Grid Creation: A 2D meshgrid of 200×200 points is created using
np.meshgrid -
Potential Calculation: For each charge, the contribution
$kq/r$ is calculated at every grid point and summed -
Field Calculation: The electric field is computed using
np.gradientto find$\vec{E} = -\nabla V$ -
Visualization:
-
matplotlib.pyplot.streamplottraces field lines by following the vector field -
matplotlib.pyplot.contourfinds and draws curves of constant potential - Charge markers are plotted with
scatterand annotated withtext
-
Since potential approaches infinity at charge locations (
r = np.sqrt((X - charge.x)**2 + (Y - charge.y)**2) + epsilonNumPy's array broadcasting is used extensively for efficiency. Instead of looping over individual grid points, operations are performed on entire arrays simultaneously:
r = np.sqrt((X - charge.x)**2 + (Y - charge.y)**2) # Vectorized distance calculation- Python: 3.7+
- NumPy: 1.19+ (for array operations and gradient calculations)
- Matplotlib: 3.3+ (for visualization and interactive widgets)
Create a requirements.txt:
numpy>=1.19.0
matplotlib>=3.3.0
I'm a physics graduate specializing in computational physics and Python development.
This project demonstrates the application of numerical methods and scientific visualization to classical electromagnetism, translating Coulomb's Law and field theory into an interactive educational tool.
Built with Python.
