# PyGraphviz: the Graphviz layout engine behind a Python API

> PyGraphviz is a Python interface to the Graphviz graph layout and visualization package, built with SWIG over the C library, and it ships binary wheels that bundle Graphviz itself, which is why the project carries a second licence file. The build sniffs the installed Graphviz version by running dot, and the maintainers still generate the bindings and fix their line endings by hand.

**pygraphviz/pygraphviz** — Python interface to Graphviz graph drawing package

- Repository: https://github.com/pygraphviz/pygraphviz
- Website: https://pygraphviz.github.io/
- Stars: 848 · Forks: 230
- Language: Python
- License: NOASSERTION
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/pygraphviz-pygraphviz

## The layout engine is Graphviz, the API is Python

PyGraphviz is a Python interface to the Graphviz graph layout and visualization package, and the README's summary of the capability is precise: with PyGraphviz you can create, edit, read, write, and draw graphs using Python to access the Graphviz graph data structure and layout algorithms.

That distinction matters. There is no new layout engine here. The graph structure, the layout algorithms and the rendering are Graphviz, and what this project provides is a way to drive them from Python, with a graph object you can mutate and then render.

It also says that PyGraphviz provides a similar programming interface to NetworkX, which is the single most useful sentence for anyone choosing between them. A graph in PyGraphviz and a graph in NetworkX feel like the same kind of object, with the same kind of methods, so a project that already uses NetworkX for graph construction and needs Graphviz for the drawing can change the import and keep most of the code.

The project is Python with C underneath, the primary language is Python, the default branch is main, and the last push was on 2026-10-15, the same day as the newest release. The website and documentation are at pygraphviz.github.io, there is a mailing list on Google Groups for discussion, and issues go to the tracker.

The topics are complex-networks, graph-visualization and python, which is the intended audience: people who already have a graph and want a picture of it.

## Five lines to a graph you can print

The README's simple example is a doctest, which tells you the library's ergonomics better than any description:

```pycon
>>> import pygraphviz as pgv
>>> G = pgv.AGraph()
>>> G.add_node("a")
>>> G.add_edge("b", "c")
>>> print(G)
strict graph "" {
        a;
        b -- c;
}
```

The graph object is AGraph, nodes and edges are added by name, and printing the object produces the DOT text that Graphviz consumes. That last part is the point of the example, because it shows that the Python object and the DOT representation are the same thing, and that you can go from a Python script to a renderable file without a separate serialisation step.

The example also shows a default that will surprise people who expect otherwise. The graph is strict, which in Graphviz means duplicate edges are merged, and the node called a is printed with a semicolon because it has no edges, while the edge between b and c is printed as a bare statement. Those are Graphviz conventions rather than PyGraphviz choices, and they are a reminder that this is a front end to another project's model.

Everything else in the library follows from the same idea, that you build and manipulate the graph in Python, and Graphviz does the layout and the drawing.

## SWIG generates the bindings, and the build sniffs the Graphviz version

The build requirements in pyproject.toml are setuptools of at least 78 and swig above 4.1.0, which tells you the bindings are generated rather than hand written, and the Makefile has a target that does exactly that:

```
swig -python pygraphviz/graphviz.i
# DOS endings to not corrupt the diff.
@unix2dos pygraphviz/graphviz.py
@unix2dos pygraphviz/graphviz_wrap.c
```

The comment in that target is a piece of history worth repeating, because it explains a step that would otherwise look pointless. The generated files are converted to DOS line endings so that a diff is not corrupted, which is a decision from an era when the project was developed on Windows and the generated wrappers were checked in.

The setup.py is where the build gets interesting, because it has to discover which Graphviz it is compiling against. It runs the dot executable with the -V flag, captures the output, and matches it against a version pattern, on the reasoning given in a comment: a GRAPHVIZ_MAJOR_VERSION macro was added in Graphviz v14.0 but is not available before, so parsing the command line version output is the only reliable way to get portable version information across all versions. The parsed major, minor and patch numbers are then passed into the SWIG build so the generated wrapper can be compiled with the right definitions. If dot cannot be found at all, the build stops with an explicit message that Graphviz must be installed to build pygraphviz from source.

There is a second custom command in setup.py, a BuildPy subclass that runs build_ext first, because SWIG generates graphviz.py during build_ext and the pure Python part has to be copied after that generation happens. That is the kind of detail that a project with a hand-rolled build accumulates, and it is also why the clean target in the Makefile removes .so files, .pyc files, __pycache__ directories, the egg-info and the tox directory.

## The wheels bundle Graphviz, and that is a licence decision

The licence section of the README has two parts, and the second one surprises people.

PyGraphviz itself is released under the 3-Clause BSD license, with a copyright notice covering 2006 to 2026 and naming the PyGraphviz developers, Aric Hagberg, Dan Schult and Manos Renieris. The repository's own metadata gives a custom classification for the project, and the pyproject.toml lists the licence as BSD-3-Clause with both licence files, LICENSE and LICENSE.graphviz, declared as license files.

The second part: the binary wheels distributed on PyPI bundle the Graphviz libraries and command-line tools, which are licensed separately under the Eclipse Public License v2.0, and that text is in LICENSE.graphviz.

That is a genuine packaging decision with real consequences. A wheel that bundles Graphviz is convenient, because a pip install gives you a working layout engine with no system Graphviz to arrange, which matters on Windows and in containers where Graphviz is not a standard package. But it also means the artefact you ship contains EPL-2.0 code, and the copyleft obligations of that licence attach to Graphviz itself rather than to your application, and the notice has to travel with the distribution.

If you build from source against your own Graphviz instead, none of that is your problem, and the project is explicit that it requires Graphviz and points at INSTALL.txt for the details. The choice is therefore between a convenient wheel with a bundled native dependency and a source build with a system dependency, and the licence difference is a good reason to make that choice deliberately rather than by accident.

## The examples, including the ones that are skipped

The examples directory is small and instructive, and one detail in the file names is worth noticing: two of the scripts are called skip_something.

There is plot_simple.py, plot_star.py, plot_attributes.py, plot_miles.py, plot_subgraph.py and plot_subgraph_boundaries.py, so the examples cover the plain case, a star graph, custom attributes, the classic miles data example with its compressed data file miles_dat.txt.gz, subgraphs and subgraph boundaries. There is an examples/README.txt tying them together.

Then there are skip_django_simple.py and skip_utf8_encoding.py. The skip prefix marks examples that are not run as part of the normal test pass, and the two names say what they are about: a Django flavoured example and an encoding case that the standard environment does not reproduce. That is a reasonable thing to see in a repository, and it is a reminder that the test environment is not identical to every environment the library is used in.

The rest of the repository is conventional and thorough. There is doc/ for the documentation, requirements/ for pinned requirement files, a MANIFEST.in for the source distribution, a Makefile for the SWIG and clean targets, RELEASE.rst and CONTRIBUTING.rst as prose documents, a .coveragerc for coverage configuration, a .pre-commit-config.yaml, and two CI configurations in .circleci/ and .github/.

The package metadata is modern in the ways that matter. It requires Python 3.10 or newer, and the classifiers list 3.10 through 3.15, both CPython and PyPy, and the C language, which is an honest description of a project that is a Python binding over a C library.

## A 2.0 line that is still moving, on a beta label

The release history is short and recent. pygraphviz 2.0.2 was published on 2026-09-16, 2.0.3 on 2026-10-01 and 2.0.4 on 2026-10-15, and the last push to the repository was on 2026-10-15 as well.

Three releases in a month, and the repository moving on the same day as the newest tag, is the profile of a maintained project rather than a dormant one. The version is dynamic in the pyproject.toml, which is the usual arrangement when a version has to be derived from the source rather than written in one place, and the project documentation points at the stable documentation URL for the released version.

The one label to notice is Development Status :: 4 - Beta, which the classifiers carry. A two-point zero release with a beta label is not a contradiction: it means the API is expected to be stable while the project still reserves the right to call the current state beta, usually because the supported platforms and the Graphviz versions it tracks are still moving.

For an adopter, the practical summary is that this is a live project with recent releases, a modern Python floor, a generated but reproducible build, and one packaging decision you need to understand before you ship it, which is that the wheels bring Graphviz along with its own licence.

## Conclusion

Adopt PyGraphviz when you need Graphviz layout quality from Python, because the data structure and the layout algorithms are the ones Graphviz ships and NetworkX does not reimplement, and the API shape is close enough to NetworkX that the switch is small. Do not adopt it if you need a self-contained pure Python install, because the wheels bundle Graphviz and its command line tools, which is a native dependency and a separate licence. Before you install, read INSTALL.txt and check whether you want the wheel or a source build against your own Graphviz, and if you build from source, expect to need SWIG and the Graphviz headers, because the bindings are generated rather than written by hand.

## FAQ

### What is PyGraphviz and how does it relate to Graphviz?

It is a Python interface to the Graphviz graph layout and visualization package. You use Python to create, edit, read, write and draw graphs, accessing the Graphviz graph data structure and layout algorithms, and the interface is deliberately similar to the one NetworkX offers.

### Do I need Graphviz installed to use PyGraphviz?

For a source build, yes. The README states that PyGraphviz requires Graphviz and points at INSTALL.txt, and the build script runs the dot executable to detect the version and stops with an explicit error if it is missing. The binary wheels on PyPI bundle the Graphviz libraries and command-line tools so a wheel install needs no separate Graphviz.

### How is the PyGraphviz binding generated?

With SWIG. The build requirements name swig above 4.1.0, the Makefile has a swig target that runs swig -python on the interface file and then converts the generated files to DOS line endings so that a diff is not corrupted, and setup.py runs the generated extension build before the pure Python files are copied.

### What licence applies to PyGraphviz and to the wheels?

PyGraphviz is released under the 3-Clause BSD license, with a notice covering 2006 to 2026 and naming its developers. The binary wheels bundle the Graphviz libraries and command-line tools, which are licensed separately under the Eclipse Public License v2.0, and that text is in a second licence file in the repository.

## Sources

- [Issues](https://github.com/pygraphviz/pygraphviz/issues)
- [Project website](https://pygraphviz.github.io/)
- [pygraphviz/pygraphviz on GitHub](https://github.com/pygraphviz/pygraphviz)
- [README](https://github.com/pygraphviz/pygraphviz/blob/main/README.md)
- [Releases](https://github.com/pygraphviz/pygraphviz/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/pygraphviz-pygraphviz
