### Commands

- background()
- clear()
- export()
- geometry()
- plot()
- size()
- speed()

### Legacy Commands

- halt()
- outputmode()
- ximport()

#### Commands

# background()

## Syntax

    background(r, g, b, a=1.0)
    background(h, s, b, a=1.0)
    background(c, m, y, k, a=1.0)
    background(k, a=1.0)
    background(color)
    background(None) # transparent backdrop
    background(*colors, angle, steps=[0,1]) # axial gradient
    background(*colors, steps=[0,1], center=[0,0]) # radial gradient

## Description

Sets the canvas background color using the same syntax as the fill(), stroke(), and color() commands. You can set the background to transparent by supplying `None` as its sole parameter (making it easier to import into Photoshop or Illustrator).

You can set the background to a gradient by passing more than one color value. For example `background('#600', 'white')` will draw a radial gradient ranging from dark red to white. Specifying an `angle` will render a linear gradient at that orientation. The optional `steps` parameter should be the same length as the number of colors in the gradient. Each entry defines the center of its corresponding color in the gradient in relative values ranging from 0–1.

## Returns

a Color object containing the defined color values

## Tutorial

Color

## Example

    background(.2)
    fill(1)
    rect(10,10, 50,50)

# clear()

## Syntax

    clear()       # erase the canvas
    clear(all)    # erase the canvas and reset drawing state
    clear(*grobs) # remove specific objects from the canvas

## Description

Erases any prior drawing to the canvas and can optionally reset the graphics state (transform, colors, and compositing) when called with the `all` argument. Calling clear() with one or more references to previously-drawn objects will remove just those objects without otherwise affecting the drawing state.

## Tutorial

Graphics State

## Example

    r = rect(0,0, 100,10) # add a rectangle
    t = poly(50,50, 25)   # add a square
    c = arc(125,125, 50)  # add a circle
    clear(r, c) # remove the rectangle & circle

# export()

## Syntax

    ... # draw to the canvas
    export("spool.pdf", cmyk=False)

    ... # draw at retina-quality to the canvas
    export("spool.png", zoom=2)

    with export("movie.mov", fps=30, bitrate=1.0):
        ... # draw movie frames

    with export("anim.gif", fps=30, loop=0):
        ... # draw gif frames

The export() command allows you to generate images and animations from within your scripts. Calling export() as part of a `with` statement will allow you to render single images, multi-page sequences, or animations.

When running the PlotDevice application, you’ll likely find it more convenient to use the File → Export as… menu items (⌘P and ⇧⌘P for images and animations respectively). But for standalone scripts that import the `plotdevice` module, the export() command is the main avenue for generating graphics.

## Saving the canvas to an image

You can call export() at any time to write the current set of graphics objects on the canvas to a single bitmap or vector image file. The only required argument is a file path (whose extension will determine the format). The optional `cmyk` argument can be set to `True` to use ‘process’ colors when exporting to a PDF, EPS, or TIFF file.

By default, bitmap images will be exported at 1:1 resolution (i.e., one pixel for each ‘point’ in the area set via size()). The `zoom` parameter defaults to `1.0` and allows you to generate arbitrarily larger (or smaller) magnifications—though sticking to round numbmers like 1, 2, and 3 will give you the best results. As a shortcut, you can also set your filename to end with an `"@…x"` to specify the zoom factor.

For instance the following will generate identical bitmaps:

    export("retina.png", zoom=2)
    export("retina@2x.png")

## Context Manager

The export() command returns a context manager that takes care of canvas-setup and file-generation for both single images and animations. By enclosing your drawing code in a `with` block, you can ensure that the correct sequence of clear() and export() calls is made automatically.

For instance these two methods of generating a PNG are functionally equivalent:

    clear(all)
    ... # (do some drawing)
    export('output.png')

    # let the context manager handle clearing and saving the canvas automatically
    with export('output.png'):
        ... # (do some drawing)

## Animations

If you specify a filename ending in `mov` (or `gif` if you also pass a `loop` or `fps` argument), the export() command will begin a multi-frame animation and return an object to help you coordinate things. You can ‘capture’ this object and give it a name (for instance, `movie`) using Python’s ‘with … as …’ syntax.

Each time you call the `movie`’s add() method, a new frame with the contents of the canvas will be added to the end of the animation. Once you’ve added the `movie`’s final frame, you must call the finish() method to wait for the video encoder’s background thread to complete its work.

As with the single-image version of the export() call, you can use the `with` statement in your code to tidy up some of the frame-drawing boilerplate. All three examples below are equivalent. Note the use of the `movie` object’s frame property (which is itself a context manager) in the final example:

    # export a 100-frame movie
    movie = export('anim.mov', fps=50, bitrate=1.8)
    for i in range(100):
        clear(all)  # erase the previous frame from the canvas
        ...         # (do some drawing)
        movie.add() # add the canvas to the movie
    movie.finish()  # wait for i/o to complete

    # export a movie (with the context manager finishing the file when done)
    with export('anim.mov', fps=50, bitrate=1.8) as movie:
        for i in range(100):
            clear(all)  # erase the previous frame from the canvas
            ...         # (do some drawing)
            movie.add() # add the canvas to the movie

    # export a movie (with the context manager finishing the file when done)
    # let the movie.frame context manager call clear() and add() for us
    with export('anim.mov', fps=50, bitrate=1.8) as movie:
        for i in range(100):
            with movie.frame:
                ... # draw the next frame

## Image sequences

If you’re generating a series of static images, export() will automatically give them consecutive names derived from the filename you pass as an argument. If the filename is a simple `"name.ext"` string, the sequence number will be appended with 4 characters of padding (`"name-0001.ext"`, `"name-0002.ext"`, etc.).

If the filename contains a number between curly braces (e.g., `"name-{4}.ext"`), that substring will be replaced with the sequence number and zero padded to the specified number of digits:

    # export a sequence of images to output-0001.png, output-0002.png, ...
    #                                output-0099.png, output-0100.png
    with export('output.png') as img:
        for i in range(100):
            with img.frame:
                ... # draw the next image in the sequence

    # export a sequence of images to 01-img.png, 02-img.png, ...
    #                                99-img.png, 100-img.png
    with export('{2}-img.png') as img:
        for i in range(100):
            with img.frame:
                ... # draw the next image in the sequence

## Multi-page PDFs

Creating PDF documents works the same way, letting you either clear(), add(), and finish() the export manually or take advantage of the `with` statement to hide the repetitive bits. Note that PDF exports use the `page` attribute rather than `frame`:

    # export a five-page pdf document
    pdf = export('multipage.pdf')
    for i in range(5):
        clear(all) # erase the previous page's graphics from the canvas
        ...        # (do some drawing)
        pdf.add()  # add the canvas to the pdf as a new page
    pdf.finish()   # write the pdf document to disk

    # export a pdf document more succinctly
    with export('multipage.pdf') as pdf:
        for i in range(5):
            with pdf.page:
                ... # draw the next page

# geometry()

## Syntax

    geometry(units)

## Description

Sets the units for angles supplied to drawing commands. By default this is `DEGREES`, but you can also use either `RADIANS` or `PERCENT`. The rotate() command will use whatever geometry-unit you select, as will the Point object’s methods and the `angle` argument used when creating Gradients.

## Tutorial

Graphics State

## Example

    # turn the canvas 1/4 of the way around using radians
    geometry(RADIANS)
    rotate(pi/2)
    # do the opposite using degrees
    geometry(DEGREES)
    rotate(-90)

# plot()

## Syntax

    plot(grob)

## Description

The plot() command will draw any PlotDevice primitive to the canvas. It’s useful in combination with the `plot` argument that can be passed to poly(), arc(), text(), image(), and friends.

When you call a drawing-related function with `plot=`False``, the object is created but not added to the canvas. You can save a reference to the object in a variable then pass it to plot() later to be drawn as-is or with additional styling in its keyword args.

## Context Manager

The plot() command can also be used as part of a `with` statement to control whether drawing commands affect the canvas by default. For instance, you could suspend drawing inside an indented code block with:

    with plot(False):
        p = poly(10,10, 30) # won't be drawn

This allows you to omit the `plot=False` argument in the individual commands, which can be convenient when creating a bunch of ‘template’ objects ahead of time.

## Tutorial

Graphics State

## Example

    # create a shape (but don't draw it immediately)
    r = rect(20,20,40,40, plot=False)
    ...
    # draw the saved shape (but override the canvas's fill color)
    plot(r, fill='red')

    # the plot keyword arg prevents this from being drawn
    o = oval(0,0,100,100, plot=False)

    # the plot() command disables drawing for the entire block
    with plot(False):
        o = oval(0,0,100,100)   # not drawn
        s = rect(100,100,10,10) # same here

# size()

## Syntax

    size(width, height, unit=px)

## Description

Sets the size of the canvas using your preferred measurement scale. If called with just `width` & `height` values, the canvas will default to using PostScript points for measurement (a.k.a. `px`).

If this command is used, it should generally be called at the very beginning of the script. An important exception to this is the use of the export() command as part of a `with` statement. In these cases it’s perfectly valid to set the size as the first line of the export-block.

If the optional `unit` arg is included, it should be one of: `px`, `pica`, `inch`, `cm`, or `mm`. Setting the canvas’s ‘default unit’ in this manner causes all subsequent drawing commands to be interpreted at that scale. The unit types can also be used to multiply values from other systems to the canvas’s units. For example `8.5*inch` will always be the width of a letter page (regardless of the canvas’s unit).

The dynamic variables `WIDTH` and `HEIGHT` can be used to obtain the canvas size.

## Tutorial

Variables

## Example

    size(20, 20, cm)
    # the canvas is 20 x 20 cm
    print(2*inch)
    >>> 5.079992238900746

# speed()

## Syntax

    speed(fps)

## Description

Sets the frame-rate for previewing animations in the application. The `fps` argument specifies the maximum speed of the animation in frames per second. Note that this is only a maximum and complex animations will likely update less frequently. Calling speed() only makes sense if your script has been written as an animation.

In an animation, your drawing code does not live in the top-level of the script, but instead is factored into a trio of commands that you define yourself: setup(), draw(), and stop(). Your setup() command is called once at the beginning of a run, and stop() is called once the run is halted. The draw() command gets called repeatedly (with the canvas being cleared between calls).

The global variable called `FRAME` will be incremented before every draw() and can be used in your code to track the passage of ‘time’.

## Tutorial

Animation

## Example

    speed(30)

    def setup(): # initialize variables, etc.
        pass

    def draw(): # draw the next frame in the animation
        pass

    def stop(): # gather up accumulated data, print summary info, etc.
        pass

#### Legacy Commands

# halt()

## Syntax

    halt()

## Description

Immediately ends an animation run.

Animations will typically run until you halt them manually using the ⌘. keyboard shortcut. The halt() command lets you ‘bail out’ of an animation from code. This can be quite useful during debugging, but we discourage using it in scripts that you share with others.

## Tutorial

Animation

## Example

    def draw():
        if FRAME==100:
            halt()

# outputmode()

## Syntax

    outputmode(mode)

## Description

Changes the way colors are displayed. While the colormode() command specifies the input of colors, outpumode() specifies the output. By default, the output mode for colors is `RGB`, but you can also set it to `CMYK` so that exported PDF’s are ready for print. Output in `RGB` will look brighter on screen, but for valid PDF documents the colors need to be in `CMYK`.

## Returns

the current output mode (`RGB` or `CMYK`)

## PlotDevice Equivalent

Choosing the output color-mode now happens as part of the application’s Export as… dialog box. If you’re calling the export() command directly, you can include a `cmyk=True` argument to override the canvas’s default mode. Otherwise exports will default to `RGB`.

## Tutorial

Color

## Example

    outputmode(CMYK)

# ximport()

## Syntax

    libname = ximport("libname")

## Description

The ximport() command is of historical interest to NodeBox users and is no longer necessary in PlotDevice. It allowed for importing ‘Libraries’ that had been installed in the `~/Library/Application Support/PlotDevice` directory.

When called with a string whose value matches the name of an installed Library, the Library will be loaded and returned as a module. In addition, a reference to the current ‘graphics context’ is handed to the module, allowing it to change the graphics state, draw to the canvas, etc.

You can assign the module to a variable of any name you choose. Most of the time it makes sense to use the same name as the Library, but you’re free to pick something shorter if it’s too much of a mouthful.

## Returns

a Python module object

## PlotDevice Equivalent

The PlotDevice Libraries have been updated to work with the standard Python `import` statement.

## Tutorial

Libraries

## Example

    colors = ximport("colors")
    background(colors.papayawhip())
    fill(colors.chocolate())
    rect(10, 10, 50, 50)