Drawing / Export Addon

This add-on provides the functionality to render a DXF document to produce a rasterized or vector-graphic image which can be saved to a file or viewed interactively depending on the backend being used.

The module provides two example scripts in the folder examples/addons/drawing which can be run to save rendered images to files or view an interactive visualisation

$ ./draw_cad.py --supported_formats
# will list the file formats supported by the matplotlib backend.
# Many formats are supported including vector graphics formats
# such as pdf and svg

$ ./draw_cad.py <my_file.dxf> --out image.png

# draw a layout other than the model space
$ ./draw_cad.py <my_file.dxf> --layout Layout1 --out image.png

# opens a GUI application to view CAD files
$ ./cad_viewer.py

Example for the usage of the matplotlib backend:

import sys
import matplotlib.pyplot as plt
from ezdxf import recover
from ezdxf.addons.drawing import RenderContext, Frontend
from ezdxf.addons.drawing.matplotlib import MatplotlibBackend

# Safe loading procedure (requires ezdxf v0.14):
try:
    doc, auditor = recover.readfile('your.dxf')
except IOError:
    print(f'Not a DXF file or a generic I/O error.')
    sys.exit(1)
except ezdxf.DXFStructureError:
    print(f'Invalid or corrupted DXF file.')
    sys.exit(2)

# The auditor.errors attribute stores severe errors,
# which may raise exceptions when rendering.
if not auditor.has_errors:
    fig = plt.figure()
    ax = fig.add_axes([0, 0, 1, 1])
    ctx = RenderContext(doc)
    out = MatplotlibBackend(ax)
    Frontend(ctx, out).draw_layout(doc.modelspace(), finalize=True)
    fig.savefig('your.png', dpi=300)

Simplified render workflow but with less control:

from ezdxf import recover
from ezdxf.addons.drawing import matplotlib

# Exception handling left out for compactness:
doc, auditor = recover.readfile('your.dxf')
if not auditor.has_errors:
    matplotlib.qsave(doc.modelspace(), 'your.png')
ezdxf.addons.drawing.matplotlib.qsave(layout: Layout, filename: str, *, bg: Optional[str] = None, fg: Optional[str] = None, dpi: int = 300, backend: str = 'agg', params: dict = None, filter_func: Callable[[DXFGraphic], bool] = None)None

Quick and simplified render export by matplotlib.

Parameters
  • layout – modelspace or paperspace layout to export

  • filename – export filename, file extension determines the format e.g. “image.png” to save in PNG format.

  • bg – override default background color in hex format #RRGGBB or #RRGGBBAA, e.g. use bg=”#FFFFFF00” to get a transparent background and a black foreground color (ACI=7), because a white background #FFFFFF gets a black foreground color or vice versa bg=”#00000000” for a transparent (black) background and a white foreground color.

  • fg – override default foreground color in hex format #RRGGBB or #RRGGBBAA, requires also bg argument. There is no explicit foreground color in DXF defined (also not a background color), but the ACI color 7 has already a variable color value, black on a light background and white on a dark background, this argument overrides this (ACI=7) default color value.

  • dpi – image resolution (dots per inches).

  • backend – the matplotlib rendering backend to use (agg, cairo, svg etc) (see documentation for matplotlib.use() for a complete list of backends)

  • params – matplotlib backend parameters

  • filter_func – filter function which takes a DXFGraphic object as input and returns True if the entity should be drawn or False if the entity should be ignored

New in version 0.14.

New in version 0.15: added argument params to pass parameters to the matplotlib backend

Changed in version 0.16: removed arguments ltype and lineweight_scaling

New in version 0.17: added argument filter_func to filter DXF entities

MatplotlibBackend

class ezdxf.addons.drawing.matplotlib.MatplotlibBackend
__init__(ax: plt.Axes, *, adjust_figure: bool = True, font: FontProperties, use_text_cache: bool = True, params: Dict = None)

PyQtBackend

class ezdxf.addons.drawing.pyqt.PyQtBackend
__init__(scene: qw.QGraphicsScene = None, *, use_text_cache: bool = True, debug_draw_rect: bool = False, params: Dict = None)

Backend Options params

Additional options for a backend can be passed by the params argument of the backend constructor __init__(). Not every option will be supported by all backends and currently most options are only supported by the Matplotlib backend.

pdsize

size for the POINT entity:

  • 0 for 5% of draw area height

  • < 0 specifies a percentage of the viewport size

  • > 0 specifies an absolute size

pdmode

see Point class documentation

linetype_renderer
  • “internal” uses the Matplotlib linetype renderer which is oriented on the output medium and dpi setting, This method is simpler and faster but may not replicate the results of CAD applications.

  • “ezdxf” replicate AutoCAD linetype rendering oriented on drawing units and various ltscale factors.This rendering method break lines into small segments which causes a longer rendering time!

linetype_scaling

Overall linetype scaling factor. Set to 0 to disable linetype support at all.

lineweight_scaling

Overall lineweight scaling factor. Set to 0 to disable lineweight support at all. The current result is correct, in SVG the line width is 0.7 points for 0.25mm as required, but this often looks too thick.

min_lineweight

Minimum lineweight.

min_dash_length

Minimum dash length.

max_flattening_distance

Maximum flattening distance in drawing units for curve approximations.

show_defpoints
  • 0 to disable defpoints (default)

  • 1 to show defpoints

show_hatch
  • 0 to disable HATCH entities

  • 1 to show HATCH entities

hatch_pattern
  • 0 to disable hatch pattern

  • 1 to use predefined Matplotlib pattern by pattern-name matching, or a simplified pattern in the PyQt backend. The PyQt support for hatch pattern is not good, it is often better to turn hatch pattern support off and disable HATCHES by setting show_hatch to 0 or use a solid filling.

  • 2 to draw HATCH pattern as solid fillings.

Default Values

Backend Option

MatplotlibBackend

PyQtBackend

point_size

2.0

1.0

point_size_relative

True

not supported

linetype_renderer

“internal”

“internal”

linetype_scaling

1.0

1.0

lineweight_scaling

1.0

2.0

min_lineweight

0.24

0.24

min_dash_length

0.1

0.1

max_flattening_distance

0.01

0.01

show_hatch

1

1

hatch_pattern

1

1

Properties

class ezdxf.addons.drawing.properties.Properties

LayerProperties

class ezdxf.addons.drawing.properties.LayerProperties

RenderContext

class ezdxf.addons.drawing.properties.RenderContext

Frontend

class ezdxf.addons.drawing.frontend.Frontend

Backend

class ezdxf.addons.drawing.backend.Backend

Details

The rendering is performed in two stages. The front-end traverses the DXF document structure, converting each encountered entity into primitive drawing commands. These commands are fed to a back-end which implements the interface: Backend.

Currently a PyQtBackend (QGraphicsScene based) and a MatplotlibBackend are implemented.

Although the resulting images will not be pixel-perfect with AutoCAD (which was taken as the ground truth when developing this add-on) great care has been taken to achieve similar behavior in some areas:

  • The algorithm for determining color should match AutoCAD. However, the color palette is not stored in the dxf file, so the chosen colors may be different to what is expected. The RenderContext class supports passing a plot style table (CTB-file) as custom color palette but uses the same palette as AutoCAD by default.

  • Text rendering is quite accurate, text positioning, alignment and word wrapping are very faithful. Differences may occur if a different font from what was used by the CAD application but even in that case, for supported backends, measurements are taken of the font being used to match text as closely as possible.

  • Visibility determination (based on which layers are visible) should match AutoCAD

See examples/addons/drawing/cad_viewer.py for an advanced use of the module.

See examples/addons/drawing/draw_cad.py for a simple use of the module.

See drawing.md in the ezdxf repository for additional behaviours documented during the development of this add-on.

Limitations

  • Rich text formatting is ignored (drawn as plain text)

  • If the backend does not match the font then the exact text placement and wrapping may appear slightly different

  • MULTILEADER renders only proxy graphic if available

  • relative size of POINT entities cannot be replicated exactly

  • only basic support for:

    • infinite lines (rendered as lines with a finite length)

    • VIEWPORT and OLE2FRAME entities (rendered as rectangles)

    • 3D entities are projected into the xy-plane and 3D text is not supported

    • vertical text (will render as horizontal text)

    • multiple columns of text (placement of additional columns may be incorrect)