G Code Plotting Python

Since I first acquired my CNC machine I started building a set of tools in Python to let me generate and manipulate gcode files. I have now released this code on GitHub under a Creative Commons Attribution-ShareAlike license in the hope it will be useful to others as well.

Disclaimer: Please be careful before using any of the gcode generated by these tools on your actual machine. Although I use it successfully myself on a range of projects I cannot guarantee that it won't damage your machine or behave differently in your environment. A good check is to run the resulting code through OpenSCAM before using it on an actuall CNC machine.

A Python 3 installation and some G-Code to plot. How you use it: Open the laserPlotter.py file with your text editor, adjust the parameters, execute it, and watch the plot appear. Aug 03, 2016 I want to read a g code file line by line, and based off of a comment at the end, do an action to it. The g code is coming out of Slic3r. Some example lines in no particular order look like this. Vertical bar chart. Data data'Year' 2018.setindex('Country name')'Life.

About The Code

So, what's in the box? The code consists of a simple class framework to load, manipulate and save .ngc files as well as a handful of simple (and complex) command line utilities. The code base is definitely a work in progress, so please don't expect a perfect 'out of box experience' - it has built up over the past 9 months and undergone several refactorings and rewrites as I added the tools and functionality I needed for a particular use case.

There is no 'pip install' option, you will just have to clone the repository and run the tools directory. You will need Python 2.6 or 2.7 to run the tools and there are a few dependencies you will need to install as well:

  1. pillow - the Python Imaging Library. This is used to generate PNG representations of gcode files.
  2. matplotlib - this is only used in the probeinfo.py utility to generate height map images from bCNC probe files.

All the tools use millimeters for units (and gcode files in inches will be converted to millimeters when they are loaded). In most cases the tools assume you are doing simple 2D operations with single cut (Z < 0) and safe (Z > 0) depths - gcode that uses a range of Z levels will probably not fare well.

To avoid having to specify parameters on every tool the library looks in the file 'gcode.json' (included in the repository) for a set of default values to use if the associated command line option is missing. That file looks like this ...

I've done my best to make the utilities self documenting, simply run them without any arguments to get a list of options available. The best way to see how it works though is to look at the source code itself.

The remainder of this post gives an overview of the classes provided and how to use them, if you are only interested in the existing set of utility programs you can skip ahead to the end of the post.

GCode and GCommand Classes

All of the supporting code lives in the util package in the repository. The two main classes of interest are GCommand which represents a single gcode command and GCode which represents a sequence of commands (basically the whole .ngc file).

You can either create a GCode instance by loading a .ngc file or by building it up line by line in your program. The GCode instance will update the bounding box that contains the cutting operations automatically.

Code

Once the GCode instance is created you can inspect the individual commands by looking at the lines attribute.

Each entry in the lines list is a GCommand instance. This splits the gcode into it's command and parameters so you can easily manipulate it.

Each of the standard parameters for a gcode instruction is added as an attribute on the GCommand instance. If the parameter has not been assigned a value the attribute will be set to None. The command itself (eg 'G00' or 'G38.2') is stored in the command attribute.

You can create a GCommand directly either by passing the command you want to use as a string or by setting the attributes after construction.

Finally you can save the modified (or created) gcode to a file with the saveGCode() function.

As a bonus you can also render the gcode to an image - this gives you a visual representation of what the result will look like.

Filters

3d plotting python

The classes above provide enough functionality to programatically create gcode either from mathematical functions or by converting other formats such as graphics files into something that can be sent to a CNC machine. The next step is to be able to modify existing files and apply transformations.

To do this the framework provides a Filter class that can be applied to a GCode instance. Each filter implements a method called apply() which will be called with each command in turn. The method can return None to indicate the line should be ignored or a sequence of GCommand instances that will replace the original.

I have already implemented a number of filters in filters.py that provide support for translation, rotation, flipping and axis swapping. One useful filter will fix arcs for you by recalculating the center point - the LineGrinder tool in particular has a bad habit of generating arc commands with poor resolution. The implementation of this filter is an adaption of the LineBender code.

Filters are applied with the clone() method on the GCode instance - this will return a new instance consisting of the modified commands. As you can see in the example above you can apply multiple filters in a single call - they will be applied in the order given.

Utilities

I have also included a set of simple utilities in the repository as well:

  • areacut.py - generate a .ngc file to cut out a rectangular area at a specified depth.
  • ngcmerge.py - append multiple .ngc files together to create a single file.
  • reorigin.py - translate the file so the minimum X and Y cutting co-ordinates are at the origin.
  • bounds.py - display the bounding box for the cutting operations in the file and optionally generate an image of the tool path.
  • multipass.py - convert a single cutting operation into multiple passes at smaller cutting depths.
  • probeinfo.py - this one doesn't actually do anything with .ngc files, it creates a height map image from a bCNC .probe file.
  • rotate.py - rotate the file by a specified angle.
  • zlevel.py - change the cutting depth and safe level for the file.

There are also a few more complex utilities in there as well. The pcbpack.py script will lay out PCB isolation routing gcode files to fit a blank PCB panel and generated combined milling, edge milling and drilling files in the process. This tool will get it's own post in the next few days.

There is also svg2ngc.py which is an incomplete implementation of a SVG to gcode converter as well as a tool to generate SVG templates for cutting out double U style boxes.

What's Next?

Now that I've pushed the code to a public repository there is a bit of clean up work I would like to do - remove some redundant files and clean up the documentation for the project. While the PCB layout tool is mostly complete (enough that I can use it on a regular basis) it still needs some tweaking and the other larger tools are not yet finished.

As I said at the start of the post, it's still a work in progress but functional enough to be useful and the framework makes it very easy to implement new tools as they are needed. I will keep adding to it over time and, if you come up with useful additions please send a pull request to have them included.

Matplotlib recognizes the following formats in the table below to specify acolor.

FormatExample
RGB or RGBA (red, green, blue, alpha)tuple of float values in a closedinterval [0, 1].
  • (0.1,0.2,0.5)
  • (0.1,0.2,0.5,0.3)
Case-insensitive hex RGB or RGBAstring.
  • '#0f0f0f'
  • '#0f0f0f80'
Case-insensitive RGB or RGBA stringequivalent hex shorthand ofduplicated characters.
  • '#abc' as '#aabbcc'
  • '#fb1' as '#ffbb11'
String representation of float valuein closed interval [0,1] forblack and white, respectively.
  • '0.8' as light gray
  • '0' as black
  • '1' as white

Single character shorthand notationfor shades of colors.

Note

The colors green, cyan,magenta, and yellow do notcoincide with X11/CSS4colors.

  • 'b' as blue
  • 'g' as green
  • 'r' as red
  • 'c' as cyan
  • 'm' as magenta
  • 'y' as yellow
  • 'k' as black
  • 'w' as white
Case-insensitive X11/CSS4 color namewith no spaces.
  • 'aquamarine'
  • 'mediumseagreen'
Case-insensitive color name fromxkcd color survey with 'xkcd:'prefix.
  • 'xkcd:skyblue'
  • 'xkcd:eggshell'

Case-insensitive Tableau Colors from'T10' categorical palette.

  • 'tab:blue'
  • 'tab:orange'
  • 'tab:green'
  • 'tab:red'
  • 'tab:purple'
  • 'tab:brown'
  • 'tab:pink'
  • 'tab:gray'
  • 'tab:olive'
  • 'tab:cyan'

'CN' color spec where 'C'precedes a number acting as an indexinto the default property cycle.

Note

Matplotlib indexes colorat draw time and defaultsto black if cycle does notinclude color.

  • 'C0'
  • 'C1'
rcParams['axes.prop_cycle'] (default: cycler('color',['#1f77b4','#ff7f0e','#2ca02c','#d62728','#9467bd','#8c564b','#e377c2','#7f7f7f','#bcbd22','#17becf']))

See also

The following links provide more information on colors in Matplotlib.
  • Color Demo Example
  • matplotlib.colors API
  • List of named colors Example

'Red', 'Green', and 'Blue' are the intensities of those colors. In combination,they represent the colorspace.

Matplotlib draws Artists based on the zorder parameter. If there are nospecified values, Matplotlib defaults to the order of the Artists added to theAxes.

The alpha for an Artist controls opacity. It indicates how the RGB color of thenew Artist combines with RGB colors already on the Axes.

The two Artists combine with alpha compositing. Matplotlib uses the equationbelow to compute the result of blending a new Artist.

Alpha of 1 indicates the new Artist completely covers the previous color.Alpha of 0 for top color is not visible; however, it contributes to blendingfor intermediate values as the cumulative result of all previous Artists. Thefollowing table contains examples.

Alpha valueVisual
0.3
1

Best Plotting Python

Note

Re-ordering Artists is not commutative in Matplotlib.

'CN' color selection¶

Matplotlib converts 'CN' colors to RGBA when drawing Artists. TheStyling with cycler section contains additionalinformation about controlling colors and style properties.

Python Plotting Tools

The first color 'C0' is the title. Each plot uses the second and thirdcolors of each style's rcParams['axes.prop_cycle'] (default: cycler('color',['#1f77b4','#ff7f0e','#2ca02c','#d62728','#9467bd','#8c564b','#e377c2','#7f7f7f','#bcbd22','#17becf'])). They are 'C1' and 'C2',respectively.

Comparison between X11/CSS4 and xkcd colors¶

The xkcd colors come from a user survey conducted by the webcomic xkcd.

95 out of the 148 X11/CSS4 color names also appear in the xkcd color survey.Almost all of them map to different color values in the X11/CSS4 and inthe xkcd palette. Only 'black', 'white' and 'cyan' are identical.

For example, 'blue' maps to '#0000FF' whereas 'xkcd:blue' maps to'#0343DF'. Due to these name collisions, all xkcd colors have the'xkcd:' prefix.

The visual below shows name collisions. Color names where color values agreeare in bold.

Python Plot Graph

Total running time of the script: ( 0 minutes 1.149 seconds)

Keywords: matplotlib code example, codex, python plot, pyplotGallery generated by Sphinx-Gallery