Adding circuit elements

All schemdraw schematics are contained within a schemdraw.Drawing object:

class schemdraw.Drawing(**kwargs)

Set up a new circuit drawing

Parameters:kwargs – arguments for customizing the drawing (see Styling).

The first step of any schematic is to create a drawing:

d = schemdraw.Drawing()

Circuit elements, such as resistors and capacitors, are added to the Drawing using the schemdraw.Drawing.add() method, which takes a dictionary defining the element as a parameter, and other keyword arguments that define the element’s position and other properties. The element definition will usually be something defined in schemdraw.elements, but can be your onw dictionary defining how to draw the element. For a description of what goes in to an element definition, see Defining custom elements.

schemdraw.Drawing.add(elm_def, **kwargs)

Add an element to the drawing

  • elm_def (dict) – element definition
  • kwargs – keyword arguments to define placement, styling, labels, etc. (see below)

an Element instance

Return type:


This method returns a schemdraw.Element object. Typically, you shouldn’t need to instantiate this object yourself; it is done using the add method, which will automatically place a new Element into the Drawing and shift it to the desired position.


The position of each element can be specified in a number of ways. If no position is given, it will start at the current drawing position, typically where the previous element ends, and in the current drawing direction. Otherwise, position can be specified using some combination of the keyword arguments to the schemdraw.Drawing.add() method.

The following schemdraw.Drawing.add() keyword arguments can be used to define the starting position and ending position of the element:

  • xy (float array [x, y]): Specifies the starting coordinate of the element. Defaults to the current drawing position (endpoint of the last drawn element.)
  • d (string) [‘up’, ‘down’, ‘left’, ‘right’]: Direction to draw the element
  • theta (float): Angle in degrees to draw the element, overrides d.
  • l (float): Specify the total length of the element in Drawing units
  • anchor (float array [x, y]): Name of the “pin” in the element to place at xy in the Drawing. Typically used for elements with more than two terminals. For example, an OPAMP element has in1, in2, and out anchors.
  • zoom (float): Zoom factor to enlarge or shrink the element

When no placement parameters are given, the element is placed at the endpoint of the last element added, and in the same direction.

d.add(elm.RES, theta=20, label='R1')
d.add(elm.RES, label='R2')  # Takes position and direction from R1

Using anchors

An anchor is a predefined position within an element. Two-terminal elements have anchors named start and end. Three-terminal elements have other anchors, for example an OPAMP has in1, in2, and out anchors. There are two ways to use anchors when placing elements. Using the anchor keyword when adding an element will align the element’s anchor position with the drawing position. Here, an opamp is placed at the end of the resistor, connected to its in1 anchor (the inverting input).

d.add(elm.RES, label='Resistor')
d.add(elm.OPAMP, anchor='in1')

Compared to anchoring the opamp at in2 (the noninverting input):

d.add(elm.RES, label='Resistor')
d.add(elm.OPAMP, anchor='in2')

Elements can also be placed starting at the anchor point of another existing element. The schemdraw.Element object returned from the add function contains attributes defining the x, y coordinates of the element’s anchors. For example, to draw an opamp and place a resistor on the output, store the return from add. Then set the xy parameter of the new element as the out attribute of the existing element:

opamp = d.add(elm.OPAMP)
d.add(elm.RES, xy=opamp.out, d='right')

Placing around existing elements

Other placement arguments can be used; these override the d or theta parameters, and are useful to make new elements line up with existing ones.

  • to (float array [x, y]): Specify the exact end coordinate of the element. Leads will be extended to the required length.
  • tox (float): Specify only the x-value of the end coordinate. Y-value will remain the same as start (for horizontal elements)
  • toy (float): Specify only the y-value of the end coordinate. X-value will remain the same as start (for vertical elements)
  • endpts (float array [[x1, y1], [x2, y2]]): Define both start and end coordinates of the element. Overrides any other positioning arguments.
C = d.add(elm.CAP)
d.add(elm.LINE, d='down')

# Now we want to close the loop, but can use `tox`
# to avoid having to know exactly how far to go.
# Note we passed the [x, y] position of capacitor C,
# but only the x value will be used.
d.add(elm.LINE, d='left', tox=C.start)

d.add(elm.SOURCE, d='up')

Note that these parameters will have no effect on elements that don’t automatically extend leads, such as most three-terminal elements.


Two more arguments control the orientation of elements. These do not affect the direction d parameter or the start and end anchors of the element.

  • flip (bool): Flip the element about its axis, for example to move the LED “light” to the other side.
  • reverse (bool): Reverse the element direction, for example to swap orientation of a diode.
d.add(elm.ZENER, label='Normal')
d.add(elm.ZENER, label='Flip', flip=True)
d.add(elm.ZENER, label='Reverse', reverse=True)

Drawing State

The schemdraw.Drawing maintains a drawing state that includes the current x, y position and drawing direction. A LIFO stack of drawing states can be used, via the schemdraw.Drawing.push() and schemdraw.Drawing.pop() method, for times when it’s useful to save the drawing state and come back to it later.

d.push()  # Save this drawing position/direction for later

d.add(elm.CAP, d='down')
d.pop()   # Return to the pushed position/direction


Labels are added to elements using other keyword arguments to add. Each label is a string, but LaTeX math is rendered when enclosed in $..$.

  • label (string): add a label in the default location for this element
  • toplabel (string): add a label above the top of the element
  • botlabel (string): add a label below the bottom of the element
  • rgtlabel (string): add a label to the right of the element
  • lftlabel (string): add a label to the left of the element
d.add(elm.RES, label='Label', botlabel='Bottom', rgtlabel='Right', lftlabel='Left')

Alternatively, a label may be a list of strings, which will be evenly-spaced along the length of the element. This allows for labeling positive and negative anlong with a component name, for example:

d.add(elm.RES, label=['$-$','$R_1$','+'])  # Using $-$ to get a proper minus sign rather than a hyphen

Several other add arguments control the behavior of labels:

  • lblofst (float): offset between the label and element
  • lblsize (int): font size of label, overriding Drawing.fontsize
  • lblrotate (bool): Rotate the label text to align with the element, to acheive vertical text for example.
  • lblloc (string): [‘top’, ‘bottom’, ‘left’, ‘right’, ‘center’]. Position for drawing the label specified by ‘label’ parameter.
d.add(elm.RES, label='no offset')
d.add(elm.RES, label='offset', lblofst=1)
d.add(elm.RES, theta=-45, label='no rotate')
d.add(elm.RES, theta=-45, label='rotate', lblrotate=True)

For more control over label behavior, use the schemdraw.Element.add_label() method. Labels can be added at arbitrary positions with any alignment.

schemdraw.Element.add_label(label, loc='top', ofst=None, align=None, fontsize=None, rotation=0)
  • label (string) – label to add
  • loc – label position with respect to element: [‘top’, ‘bot’, ‘lft’ ‘rgt’, ‘center’], or name of an anchor defined in this element
  • ofst – offset between element and label. Can be (x,y) list for ‘center’ or anchor loc, float otherwise
  • align – label alignment as tuple of (horizontal, vertical). Horizontal can be [‘center’, ‘left’, ‘right’], and vertical [‘center’, ‘top’, ‘bottom’]
  • fontsize – font size for label
  • rotation (float) – rotation angle, in degrees

Current Labels

To label the current through an element, the ARROWI element is defined. Typically, it can be added alongside an existing element using the schemdraw.Drawing.labelI() method:

schemdraw.Drawing.labelI(elm, label='', arrowofst=0.4, arrowlen=2, reverse=False, top=True)

Add a current arrow along the element

  • elm – schemdraw.Element to add arrow to
  • label – string or list of strings to space along arrow
  • arrowofst – distance between element and arrow
  • arrowlen – length of arrow in drawing units
  • reverse (bool) – reverse the arrow, opposite to elm.theta
  • top (bool) – draw the arrow on top of the element
R1 = d.add(elm.RES)
d.labelI(R1, '10 mA')

Alternatively, current labels can be drawn inline as arrowheads on the leads of 2-terminal elements using schemdraw.Drawing.labelI_inline().

schemdraw.Drawing.labelI_inline(elm, label='', botlabel='', d='in', start=True, ofst=0)

Draw an inline current arrow on the element.

  • elm – schemdraw.element to add arrow to
  • label (string) – string label above the arrowhead
  • botlabel (string) – string label below the arrowhead
  • d (string) – arrowhead direction, either ‘in’ or ‘out’
  • start (bool) – place arrowhead near start (or end) of element
  • ofst – additional offset along elemnet leads
R1 = d.add(elm.RES)
d.labelI_inline(R1, '$i_1$', d='in')

Loop currents can be added using schemdraw.Drawing.loopI().

schemdraw.Drawing.loopI(elm_list, label='', d='cw', theta1=35, theta2=-35, pad=.2)

Draw an arc to indicate a loop current bordered by elements in list

  • elm_list (list) – boundary elements in order of top, right, bot, left
  • label – text label for center of loop
  • d – arrow direction [‘cw’, ‘ccw’]
  • theta1 – start angle of arrow arc (degrees). Default 35.
  • theta2 – end angle of arrow arc (degrees). Default -35.
R1 = d.add(elm.RES)
C1 = d.add(elm.CAP, d='down')
D1 = d.add(elm.DIODE_F, d='left')
L1 = d.add(elm.INDUCTOR, d='up')
d.loopI([R1, C1, D1, L1], d='cw', label='$I_1$')


When creating a new drawing, the keyword arguments to schemdraw.Drawing are used to set default styles such as colors and fontsize.

  • unit (float): default length of a 2-terminal element, including leads. The zigzag portion of resistor element is length 1 unit, and by default the total length is 3 units.
  • inches_per_unit (float): Inches per unit to scale drawing into real dimensions
  • txtofst (float): default distance from element to text label
  • fontsize (int): default font size for all labels
  • font (string): matplotlib font-family name
  • color (strong): matplotlib color name to apply to all circuit elements
  • lw (float): default line width
  • ls (stirng): default line style (matplotlib style name)

The Drawing color, lw, and ls parameters apply to all elements, unless overriden in argumetns to schemdraw.Drawing.add(). When adding an element, it’s indivudal options are:

  • color (string): matplotlib color name for the element
  • ls (string): line style for the element
  • lw (float): line width for the elemlent
  • fill (string): fill color name (only used on closed-path elements)
  • zorder (int): z-order for specifying which elements are drawn first.
d = schemdraw.Drawing(color='blue')  # All elements are blue unless specified otherwise
d.add(elm.DIODE, fill='red')
d.add(elm.RES, fill='purple')          # Fill has no effect on this non-closed element
d.add(elm.RBOX, color='orange', ls='--')
d.add(elm.RES, lw=5)