# User:Geek3/VectorFieldPlot

Field of four electric charges generated with VFPt

VectorFieldPlot (VFPt) is a python script that creates high quality fieldline plots in the svg vectorgraphics format.

VectorFieldPlot was specially designed for the use in Wikimedia Commons. The lack of physical correct high-quality fieldplots in Wikimedia Commons has inspired me to compensate for this and provide a tool that enables users to create fieldplots as they require. VectorFieldPlot has grown beyond the stage of a small simple script that might already perform the task of creating plots of physical fields. Instead, it tries to fulfill its requirements the best way possible, which are namely:

• physical correctness / accuracy
• small file size / rendering efficiency
• image clarity and beauty
• image reusability

Other aspects are only of secondary order. VectorFieldPlot will not perform best at:

• code simplicity
• easy usage
• execution speed
• fancy graphical effects

## Code

VectorFieldPlot is written in python and uses many features of scipy as well as lxml. It can be directly executed after you inserted the description of your image at the end of the program code.

## How it works

### Field calculation

VectorFieldPlot provides formulas to calculate the field at any given point in the image plane. The user can put together some given field-generating elements as charges or wires. The fields of those elements are added together and constitute the total field.

### Field line integration

Each field line starts at a user-given point. It is then carried forward using the classical fourth order Runge-Kutta method with stepsize adaption. Well, scipy does provide us a routine for things like that, namely odeint. Nevertheless VectorFieldPlot uses it's own routine, since there are tons of special cases like singularities, edges or loop closure, which all need their special treatment.

The integration steps from point to point until it exceeds some given limits, hits a singularity or closes a loop. After that, a dense output routine is provided, which makes the complete fieldline accessible as an efficient parametric function.

With some field elements there occur non differentiable locations. In this cases VectorFieldPlot provides some sophisticated routines to detect that, locate them precisely and walk right over them without generating significant errors.

### Polyline creation

VectorFieldPlot is supposed to create vector output. Hence all paths need to be represented in an adequate way. Cubic bezier curves are one way to do this, but the inconvenience to adapt them to a given curve within given accuracy limits has made simple straight line segments the first choice. VectorFieldPlot runs an iterative process of putting line segments on the path, meassuring the resulting errors and accordingly adapting the segment length. The result is a quite memory efficient path, that satisfies given accuracy requirements well beyond observable deviations.

### Image export

VectorFieldPlot uses the lxml library to generate xml and especially svg code. All image elemets are translated into the svg language and written to the image file. The vector images can be viewed directly by firefox, eye of gnome, rsvg-view and many more. Graphics programes like gimp allow for conversation to png raster images if necessary.

## Usage

VectorFieldPlot is used by pasting your image-defining code right at the end of the program file. With a python environment installed, the program can be executed directly and your image file will be written to the local directory.

The definition of an image inside of VectorFieldPlot basically consists of three steps:

### Setting up the field

Create the image document:

doc = FieldplotDocument('VFPt charges plus minus', width=800, height=600, unit=100)


This intances the FieldplotDocument class which represents an image environment and has the ability to be written to an image file later on.
parameters of FieldplotDocument:

• name: Name of the image and the file it will be saved to
• width (800): width of the image in pixels
• height (600): height of the image in pixels
• digits (3.5): accuracy of the field lines in units, used for calculating the space between points and rounding of numbers. It is recommended to use 2 < digits ≤ 5
• unit (100): number of pixels of one unit
• center ([width/2, height/2]): position of the coordinate system center in pixels
• licence ('GFDL-cc'): licence of the image ('GFDL-cc' and None are provided)
• commons (False): Add a link to Wikimedia Commons (useful if the image will be published there under the same name)

Set up the field:

field = Field({'monopoles':[ [-1, 0, 1] ]})


The Field-class contains the theoretical setup and privides all functions to calculate the physical field.
Field has only one parameter:

field.add_element('monopoles', [ [1.5, 0, -1] ])


### Integrate the fieldline path

The user has to choose a startpoint. If the direction at this point is ambiguous, a start velocity should also be provided:

line = FieldLine(field, [-1, 0], start_v=[0, 1], directions='forward')


This instances a field line and computes it's progression.
parameters of FieldLine:

• field: needs to be a valid Field instance
• start_p: list [x, y] where the line computation will start
• start_v (None): optional initial direction. This makes only sence, if the field direction at start_p is ambiguous, e.g. at a point charge
• start_d (None): optional first integration step (should be small). Useful eg. if the integration starts at a dipole.
• directions ('forward'): Can be 'forward', 'backward' or 'both'. This tells the directions, to which the fieldline will be traced.
• maxn (1000): maximum number of integration steps or tries.
• maxr (300): maximum line length in units
• hmax (1.0): maximum integration step width in units
• pass_dipoles (0): maximum number of dipoles to be passed through (None means no limit)
• path_close_tol (5e-3): distance tolerance to close fieldline loops
• stop_funcs (None): [func_backward, func_forward], two functions that stop the integration immediately where they evaluate positive
• bounds_func (None): a function which adds additional image bounds where it evaluates positive. The fieldlines are truncated after the integration process.

### Drawing content to the image document

Draw a field line with it's arrows:

doc.draw_line(line)


parameters of FieldplotDocument.draw_line:

• fieldline: needs to be a valid FieldLine instance
• maxdist (10): maximum point distance in the drawn path in units
• linewidth (2): linewidth in pixels
• linecolor ('#000000'): color of fieldlines and arrows
• attributes ('[]'): list of valid svg attribute and value pairs as lists
• arrows_style (None): style of arrows as a dictionary. Possible parameters are:
• min_arrows (1): minimum number of arrows per fieldline
• max_arrows (None): maximum number of arrows per fieldline
• dist (1.0): average distance between two arrows in units
• scale (1.0): scaling factor of arrows relative to linewidth
• offsets ([0.5, 0.5, 0.5, 0.5]): relative arrow distance at line ends ([start, leaving image border, entering image border, end])
• fixed_ends ([False, False, False, False]): Do not stretch arrow distance at those positions spcified in offsets.

Draw all symbols in our Field of one kind:

doc.draw_charges(field)


possible symbols:

• draw_charges, draw_currents, draw_magnets, charges and currents can take scale as parameter.

Self-defined objects can be drawn via

doc.draw_object('circle', {'cx':0, 'cy':0, 'r':1})


with parameters :

• name: svg specified name: circle, path, g, rect etc.
• params: a dictionary of valid svg parameters
• group (None): a previously drawn object which has type “g”. The new object will be a sub-element.

### Writing content to file

doc.write()


parameters of FieldplotDocument.write:

• filename (FieldplotDocument.name): the target filename (without .svg extension)

## Field elements

When you create a Field in VectorFieldPlot, the main parameter will be a python dictionary, which includes the name of each field component, and a list of argument lists, which hold the essential parameters of this component. E.g.:

field = Field({'monopoles':[[-1,0,1], [1,0,-1]]})


The following elements are included in VectorFieldPlot and can be used right away:

### homogeneous (Fx, Fy)

Create a constant field over the complete image plane.
parameters:

• Fx, Fy: x- and y component of the constant field

### monopoles (x, y, charge)

Create an electric or magnetic monopole i.e. a charge.
parameters:

• x, y: position of the monopole ($\vec r\,'$)
• charge: positive or negative magnitude of the charge ($q$)
$\vec F_\mathrm{m}(\vec r\,' + \vec r) = \frac{q}{4\pi}\cdot\frac{\vec r}{|\vec r|^3}$

### dipoles: (x, y, px, py)

Create an electric or magnetic point-shaped dipole.
parameters:

• x, y: position of the dipole ($\vec r\,'$)
• px, py: components of the dipole magnitude ($\vec p$)
$\vec F_\mathrm{p}(\vec r\,' + \vec r) = \frac{3(\vec p\cdot\vec r)\vec r - (\vec r\cdot\vec r)\vec p}{4\pi|\vec r|^5}$

### quadrupoles: (x, y, phi, q)

Create an electric or magnetic point-shaped quadrupole. One quadrupole element has a cylindric symmetry around the p-direction with positive charges at the ends and a negative charge in the center.
parameters:

• x, y: position of the quadrupole ($\vec r\,'$)
• phi: angular direction of the quadrupole from x- to y-axis in radians ($\vec p = (\cos \varphi, \sin \varphi)$)
• q: positive or negative magnitude
$\vec F_\mathrm{q}(\vec r\,' + \vec r) = 3q\cdot\frac{(5(\vec r\cdot\vec p)^2 - r^2p^2)\,\vec r - 2r^2(\vec r\cdot\vec p)\,\vec p}{4\pi|\vec r|^7}$

### wires: (x, y, I)

Create an infinite wire perpendicular to the image plane carrying the current I out of the image plane
parameters:

• x, y: position of the wire ($\vec r\,'$)
• I: current
$\vec F_\mathrm{w}(\vec r\,' + \vec r) = I\hat{\vec z}\times\frac{\vec r}{2\pi\,r^2}$

### charged_planes: (x0, y0, x1, y1, charge)

Create a homogeneous charged plane perpendicular to the image and expanding to infinity
parameters:

• x0, y0: first edge
• x1, y1: second edge
• charge: charge per unit length in z-direction

### ringcurrents: (x0, y0, phi, R, I)

Create the magnetic field of a round ring with it's axis of symmetry inside the image plane
parameters:

• x0, y0: ring center
• phi: angular direction of the ring axis from x- to y-axis in radians
• R: radius of the ring
• I: current through the ring (clockwise relative to axis direction)

### coils: (x0, y0, phi, R, Lhalf, I)

Create the magnetic field of an ideal coil with it's axis of symmetry inside the image plane. The field is also correct for cylindrical magnets!
parameters:

• x0, y0: ring center
• phi: angular direction of the coil axis from x- to y-axis in radians ($\vec p = (\cos \varphi, \sin \varphi)$)
• R: radius of the coil
• Lhalf: half length of the coil
• I: current through the coil times it's winding number (clockwise relative to axis direction)

## Examples

All images: Category:Created with VectorFieldPlot

## Improvements and bugs

VectorFieldPlot is some complicated piece of code. I'm absolutely sure there are quite some bugs that wait for their chance to appear. If you should discover one or you are confronted with some strange behaviour, the best way is to use the discussions page. Avoid making modifications to the source code at this page directly, since it will make me loose the overview somehow. If you should have ideas, improvements or patches, post it at the discussions page or create your own clone of VectorFieldPlot according to the licence terms.

## Future developments

VectorFieldPlot is extensible in many imaginable ways. The most likely extensions that may come up in the forseeable future, are:

• drawing of equipotential lines and areas
• creation of animations
• inclusion of metal surfaces