Schemdraw

repository·master·Indexed 42 days ago

https://github.com/cdelker/schemdraw

A Python package for producing high-quality schematic diagrams, including electrical circuits, digital timing diagrams, state machines, and flowcharts. It features a comprehensive library of electrical components, logic gate tools, truth table and Karnaugh map generation, and support for both U.S. and IEC standard styles.

Tokens
40.2K
Snippets
132
Records
151
Agent score
54%

What's inside Schemdraw

  1. Overview of schemdraw capabilities

    master

    Schemdraw supports several types of diagrams beyond standard electrical circuits:

    • Electrical Schematics: Includes symbols for resistors, capacitors, diodes, transistors, opamps, and signal processing elements.
    • Digital Timing Diagrams
    • State Machine Diagrams
    • Flowcharts
  2. Explore Electrical Elements in schemdraw

    master

    Schemdraw provides a comprehensive library of electrical components organized by their terminal count and functional type. You can import these elements from the schemdraw.elements submodules to build circuit diagrams.

    Component Categories:

    • Two-Terminal Elements: Found in schemdraw.elements.twoterm and schemdraw.elements.sources. These include standard components like resistors, capacitors, and power sources.
    • One-Terminal Elements: Found in schemdraw.elements.oneterm. These are components that connect to a single node (e.g., ground).
    • Switches: Found in schemdraw.elements.switches.
    • Lines, Cables, and Connectors: Use schemdraw.elements.lines, schemdraw.elements.cables, and schemdraw.elements.connectors to define the paths between components.
    • Active Components: Includes Transistors (schemdraw.elements.transistors), Transformers (schemdraw.elements.xform), and Opamps/Integrated Circuits (schemdraw.elements.opamp and schemdraw.elements.intcircuits).
    • Other/Miscellaneous: Includes specialized components in schemdraw.elements.misc, schemdraw.elements.compound, schemdraw.elements.twoports, and schemdraw.elements.tubes.
  3. Group Signals in Timing Diagrams

    master

    You can nest signals into groups by providing a list of lists within the signal key. The first element of the list can be a group name, followed by lists representing the sets of signals within that group.

    logic.TimingDiagram(
        {'signal': ['Group',
          ['Set 1',
            {'name': 'A', 'wave': '0..1..01.'},
            {'name': 'B', 'wave': '101..0...'}],
          ['Set 2',
            {'name': 'C', 'wave': '0..1..01.'},
            {'name': 'D', 'wave': '101..0...'}]
        ]})
  4. Use Breadboard anchors for component placement

    master

    The pictorial.Breadboard element provides specific anchors for precise component placement.

    • Center Block Pins: Use a combination of column letter and row number (e.g., bb.A1 for the top-left pin).
    • Power Strips:
      • Left side: L1_x (first column) or L2_x (second column), where x is the row number.
      • Right side: R1_x or R2_x.

    Note: Some rows in the power strips (like row 6) may not be defined and cannot be used as anchors.

    To place an element at a specific breadboard pin, use the .at() method with the anchor name.

    with schemdraw.Drawing():
        bb = pictorial.Breadboard()
        # Place a dot at pin A1
        elm.Dot(radius=.15).at(bb.A1).color('red')
        # Place a dot at the first left power strip, row 1
        elm.Dot(radius=.15).at(bb.L1_1).color('cyan')
  5. Access and use element anchors

    master

    All elements have predefined anchor positions (e.g., a BJT has base, emitter, and collector; two-terminal elements have start, center, and end).

    Once an element is placed in a drawing, you can access its anchor positions in two ways:

    1. Attribute access: element.anchor_name (e.g., Q.base).
    2. Bracket access: element['anchor_name'] (useful if the anchor name contains special characters like dots).

    Note: Anchor positions are relative to the drawing origin and are only available after the element has been placed in a drawing. You can inspect all available anchors before placement using the .anchors attribute, which returns a dictionary of anchors relative to the element's origin.

    with schemdraw.Drawing() as d:
        d.config(fontsize=10)
        # Assigning to a variable allows anchor access
        bjt = elm.BjtNpn()
        bjt.label('base', 'base', color='blue')
        
        # Accessing anchors after placement
        print(bjt.base) 
        print(bjt['base'])
  6. Compare Matplotlib and SVG backends

    master

    Choose the SVG backend if:

    • You want to avoid Matplotlib/Numpy dependencies (useful for small executable bundles).
    • You need higher performance (4-10x faster drawing speed).

    Choose the Matplotlib backend if:

    • You need to use Matplotlib functionality to customize the schematic after it is drawn.
    • You need to render directly to non-SVG image formats without extra conversion steps.
  7. Use Single-Terminal elements

    master

    Single-terminal elements are drawn around a single point and do not move the current drawing position. These are useful for ground, antennas, and connection dots.

    Common single-terminal elements:

    • Power/Ground: Ground(), GroundSignal(), Vss(), Vdd()
    • Antennas: Antenna(), AntennaLoop()
    • Dots: Dot(), DotDotDot(), NoConnect()
  8. Use the flow module for flowcharting

    master

    Flowchart elements are located in the schemdraw.flow module. You can use these elements to create standard flowchart shapes like Start, Box, Decision, Circle, and State. Elements can be connected using Arrow, Line, Wire, or specialized connection methods like Arc2 and ArcLoop for state machines.

    from schemdraw import flow
    import schemdraw
    
    with schemdraw.Drawing() as d:
        flow.Start().label('START')
        flow.Arrow().down()
        flow.Decision(w=5, h=4).label('Is this a trap?')
  9. Group elements using ElementCompound

    master

    Use schemdraw.elements.compound.ElementCompound to create a new element composed of multiple other elements. Unlike ElementDrawing, which wraps a drawing, ElementCompound acts like a Drawing itself, allowing you to add elements within a setup method.

    Key Features:

    • Elements added via self.add() in the setup method are part of the compound element.
    • Elements assigned to an attribute of the class have absolute anchor positions accessible via index notation (e.g., instance['attr_name.anchor']).
    from schemdraw import elements as elm
    
    class RC(elm.ElementCompound):
        def setup(self):
            # Add elements using self.add()
            self.r = self.add(elm.Resistor().length(1).scale(.5))
            self.c = self.add(elm.Capacitor().length(1).scale(.5))
            # Set parameters based on other elements
            self.elmparams['drop'] = self.c.end
    
    with schemdraw.Drawing() as d:
        r1 = RC()
        r2 = RC()
        # Accessing an internal anchor of the second instance
        print(r2['r.end'])
  10. Add voltage and current labels

    master

    Schemdraw provides specialized elements for labeling electrical properties:

    Voltage Labels

    • Multi-point labels: Pass a list or tuple of strings to .label() to space them evenly along an element (e.g., ('--', '$V_1$', '+')).
    • Gap labels: Use elm.Gap() to label voltage across a terminal or gap.
    • Arc labels: Use elm.VoltageLabelArc().at(element).label('V1') to draw a voltage label as an arc over an element.

    Current Labels

    • Standard Current Label: Use elm.CurrentLabel().at(element).label('10 mA'). For transistors, it follows sensible bias currents by default.
    • Inline Current Label: Use elm.CurrentLabelInline(direction='in'|'out').at(element).label('10 mA') to draw arrowheads directly on the leads of 2-terminal elements.
    • Loop Current: Use elm.LoopCurrent([e1, e2, e3, e4], direction='cw'|'ccw').label('$I_1$') to label a loop of four elements.
    • Impedance Label: Use elm.ZLabel().at(element).label('$Z_{in}$') for right-angle arrows indicating impedance at a node.
    import schemdraw
    from schemdraw import elements as elm
    
    # Voltage across a gap
    with schemdraw.Drawing():
        elm.Line().dot(open=True)
        elm.Gap().label(('–', '$V_o$', '+'))
        elm.Line().idot(open=True)
    
    # Current through a resistor
    with schemdraw.Drawing():
        R1 = elm.Resistor()
        elm.CurrentLabel().at(R1).label('10 mA')
    
    # Loop current
    with schemdraw.Drawing():
        R1, C1 = elm.Resistor(), elm.Capacitor().down()
        D1, L1 = elm.Diode().fill(True).left(), elm.Inductor().up()
        elm.LoopCurrent([R1, C1, D1, L1], direction='cw').label('$I_1$')
  11. Configure drawing and global styles

    master

    Schemdraw provides three levels of styling hierarchy:

    1. Drawing level: Use Drawing.config() to apply styles to all elements within a specific drawing instance. Parameters include color, linewidth, font, fontsize, linestyle, fill, background_color, and the default 2-Terminal element length.
    2. Global level: Use schemdraw.config() to apply styles to every new drawing created during the current Python session.
    3. Element level: Using setter methods or keyword arguments on specific elements (highest priority).

    Styling Hierarchy (Highest to Lowest Priority):

    1. Setter methods (e.g., .fill()) called after instantiation.
    2. Keyword arguments provided during instantiation.
    3. User-defined Element.defaults.
    4. Element definition defaults.
    5. Drawing.config() settings.
    6. schemdraw.config() settings.
    import schemdraw
    import schemdraw.elements as elm
    
    # Set global defaults
    schemdraw.config(lw=1, font='serif')
    
    # Set drawing-specific defaults
    with schemdraw.Drawing(color='blue', fill='lightgray') as d:
        elm.Resistor().label('100KΩ')