A Python interface to a large-format pen plotter

HPGL Files

HPGL is the Hewlett-Packard Graphics Language. This language defines a series of drawing commands that plotters and printers can interpret and use to create their output. HPGL files are plain text and use the following format:

This format is repeated until all data has been written. Table 1 shows the primary commands that Inkscape uses.

HPGL Commands

Here are the first few commands of poker_red.hpgl – the red layer of the poker poster I am plotting for this project.

This series begins with IN; that is, initialize the plotter. Then, SP2 says "go get pen number 2" (the red one in my current pen carriage). PU7138,12166 says move to coordinates 7138 by 12166, then PD7108,12166 draws the first line segment. This continues until the end of the file.

HPGL also provides commands for text output from strings, circles, arcs, and other basic geometric shapes. This allows a data analysis program to generate a graph by sending commands directly to the plotter. Because Inkscape already has many of these functions built in, it just dumps the entire drawing as Pen Up and Pen Down commands, rather than translating Inkscape objects to HPGL objects.

Plotting, Start to Finish

To begin the process, I first cut a sheet of paper and load the plotter. Getting the paper square in the machine takes a little bit of practice (Figure 3). If the paper is not square, it may wrinkle or tear. After the paper is loaded, the plotter rolls it back and forth a few times. Once the paper is square, I'm ready to start the software. Figure 3: The paper loaded and ready to plot. The yellow warning triangle on the right-hand side warns operators not to get their hair caught in the rollers.

The plotting program has two menus: files (numbered commands) and plotter (lettered commands). I use 1) Open a file to open each HPGL file (Figure 4). They will show up in the file list on the bottom of the screen, and the most recently opened file will be shown on the right in list format. (See the "Creating HPGL Files" box for more information.)

Creating HPGL Files

The first step in plotting is to have a file to plot. I decided to help my friend Paul remember the order of poker hands by creating a handy poster in Inkscape.

Once my drawing is finished, I create a separate layer in Inkscape for each color I want to plot. Each layer will become a separate HPGL file. Red had the fewest elements, so I moved them to their own layer, leaving black elements in place.

To create the HPGL files, I hide all the layers (click on the eyeball to turn them off), then turn the layers on one at a time. For each layer I choose File | Save As and then choose HP Graphics Language as my output type. It will give me a few options, but the last two are the most important: pen number and plot invisible layers. Pen number is the color to use for this layer and corresponds to the pens in the plotter carriage. The operator must make sure the right color pen is in the right slot; the plotter doesn't know the difference. Plot invisible layers needs to be unchecked so that the other layers (colors) don't show up in this file.

You'll end up with an HPGL file for each color that you want in the final product. Figure 4: The screen layout of the plotter program. The file browser (not shown) redraws the entire screen when active.

Most often, multiple HPGL files will be different colors of the same drawing, but they could also be different drawing elements. For example, a graph might contain blank axes as one file and different data sets as additional files.

Once each file is loaded, the arrow keys navigate between them. The "active" file, denoted by a '>', will receive any flip or shift commands. I can also view the file graphically. Choosing 5) Preview file will use Pygame to create a graphics window and draw the file into it (Figure 5). The graphics window appears on the Raspberry Pi's monitor, which sits behind the plotter. Figure 5: The file I will plot shows poker hand rankings from highest to lowest. Each color will be exported to a separate HPGL file so that the appropriate color pen can be used to draw it.

The next step is to connect to the plotter. Once the connection is successful, the program will ask the plotter for the dimensions of the currently loaded paper and display that next to the plotter menu.

Pressing P starts the plotting process. As commands are sent to the plotter, the file display on the right will scroll automatically to show the progress. A bar graph at the bottom line of the screen shows the current state of the plotter's buffer. Initially, this will drop very quickly because the plotter is getting the pen (a very slow process). As plotter starts drawing lines, the bar graph will oscillate back and forth for the remainder of the plotting job (Figure 6). Figure 6: The finished poster, not yet unloaded from the plotter. It took about 45 minutes, with most of the time spent on the details of the court cards.
[null, {"document_url": "http://www.raspberry-pi-geek.com/Archive/2015/11/A-Python-interface-to-a-large-format-pen-plotter/(offset)/2", "unformatted_src": "/var/rpi/storage/images/archive/2015/11/a-python-interface-to-a-large-format-pen-plotter/figure-3/18437-1-eng-US/Figure-3_large.png", "src": "https://www.raspberry-pi-geek.com/var/rpi/storage/images/archive/2015/11/a-python-interface-to-a-large-format-pen-plotter/figure-3/18437-1-eng-US/Figure-3_large.png", "formatted_filename": "Figure large"}, null, {"document_url": "http://www.raspberry-pi-geek.com/Archive/2015/11/A-Python-interface-to-a-large-format-pen-plotter/(offset)/2", "unformatted_src": "/var/rpi/storage/images/archive/2015/11/a-python-interface-to-a-large-format-pen-plotter/figure-4/18440-1-eng-US/Figure-4_large.png", "src": "https://www.raspberry-pi-geek.com/var/rpi/storage/images/archive/2015/11/a-python-interface-to-a-large-format-pen-plotter/figure-4/18440-1-eng-US/Figure-4_large.png", "formatted_filename": "Figure large"}, null, {"document_url": "http://www.raspberry-pi-geek.com/Archive/2015/11/A-Python-interface-to-a-large-format-pen-plotter/(offset)/2", "unformatted_src": "/var/rpi/storage/images/archive/2015/11/a-python-interface-to-a-large-format-pen-plotter/figure-5/18443-1-eng-US/Figure-5_large.png", "src": "https://www.raspberry-pi-geek.com/var/rpi/storage/images/archive/2015/11/a-python-interface-to-a-large-format-pen-plotter/figure-5/18443-1-eng-US/Figure-5_large.png", "formatted_filename": "Figure large"}, null, {"document_url": "http://www.raspberry-pi-geek.com/Archive/2015/11/A-Python-interface-to-a-large-format-pen-plotter/(offset)/2", "unformatted_src": "/var/rpi/storage/images/archive/2015/11/a-python-interface-to-a-large-format-pen-plotter/figure-6/18446-1-eng-US/Figure-6_large.png", "src": "https://www.raspberry-pi-geek.com/var/rpi/storage/images/archive/2015/11/a-python-interface-to-a-large-format-pen-plotter/figure-6/18446-1-eng-US/Figure-6_large.png", "formatted_filename": "Figure large"}, null, {"document_url": "http://www.raspberry-pi-geek.com/Archive/2015/11/A-Python-interface-to-a-large-format-pen-plotter/(offset)/2", "unformatted_src": "https://developer.android.com/images/brand/en_generic_rgb_wo_45.png", "src": "https://developer.android.com/images/brand/en_generic_rgb_wo_45.png", "formatted_filename": "en generic rgb wo", "alt_text": "Get it on Google Play", "rendered_width": 102, "rendered_height": 35}, null, {"document_url": "http://www.raspberry-pi-geek.com/Archive/2015/11/A-Python-interface-to-a-large-format-pen-plotter/(offset)/2", "unformatted_src": "https://developer.android.com/images/brand/en_generic_rgb_wo_45.png", "src": "https://developer.android.com/images/brand/en_generic_rgb_wo_45.png", "formatted_filename": "en generic rgb wo", "alt_text": "Get it on Google Play", "rendered_width": 102, "rendered_height": 35}, null, {"document_url": "http://www.raspberry-pi-geek.com/Archive/2015/11/A-Python-interface-to-a-large-format-pen-plotter/(offset)/2", "unformatted_src": "/var/rpi/storage/images/media/images/magazine-covers/rpg_23_cover_shop_us/30142-1-eng-US/RPG_23_Cover_Shop_US_listitem.png", "src": "https://www.raspberry-pi-geek.com/var/rpi/storage/images/media/images/magazine-covers/rpg_23_cover_shop_us/30142-1-eng-US/RPG_23_Cover_Shop_US_listitem.png", "formatted_filename": "RPG Cover Shop US listitem"}, null]