qml.circuit_drawer.MPLDrawer

class MPLDrawer(n_layers, n_wires, wire_options=None, figsize=None)[source]

Bases: object

Allows easy creation of graphics representing circuits with matplotlib

Parameters
  • n_layers (int) – the number of layers

  • n_wires (int) – the number of wires

Keyword Arguments
  • wire_options=None (dict) – matplotlib configuration options for drawing the wire lines

  • figsize=None (Iterable) – Allows users to specify the size of the figure manually. Defaults to scale with the size of the circuit via n_layers and n_wires.

Example

drawer = MPLDrawer(n_wires=5, n_layers=5)

drawer.label(["0", "a", r"$|\Psi\rangle$", r"$|\theta\rangle$", "aux"])

drawer.box_gate(layer=0, wires=[0, 1, 2, 3, 4], text="Entangling Layers", text_options={'rotation': 'vertical'})
drawer.box_gate(layer=1, wires=[0, 1], text="U(θ)")

drawer.box_gate(layer=1, wires=4, text="Z")

drawer.SWAP(layer=1, wires=(2, 3))
drawer.CNOT(layer=2, wires=(0, 2))

drawer.ctrl(layer=3, wires=[1, 3], control_values = [True, False])
drawer.box_gate(layer=3, wires=2, text="H", box_options={'zorder': 4},
    text_options={'zorder': 5})

drawer.ctrl(layer=4, wires=[1, 2])

drawer.measure(layer=5, wires=0)

drawer.fig.suptitle('My Circuit', fontsize='xx-large')
../../_images/example_basic.png

Matplotlib Integration

This class relies on matplotlib. As such, users can extend this class via interacting with the figure drawer.fig and axes drawer.ax objects manually. For instance, the example circuit manipulates the figure to set a title using drawer.fig.suptitle. Users can save the image using plt.savefig or via the figure method drawer.fig.savefig.

As described in the next section, the figure supports both global styling and individual styling of elements with matplotlib styles, configuration, and keywords.

Formatting

You can globally control the style with plt.rcParams and styles, see the matplotlib docs . If we customize plt.rcParams before executing our example function, we get a different style:

plt.rcParams['patch.facecolor'] = 'white'
plt.rcParams['patch.edgecolor'] = 'black'
plt.rcParams['patch.linewidth'] = 2
plt.rcParams['patch.force_edgecolor'] = True
plt.rcParams['lines.color'] = 'black'
../../_images/example_rcParams.png

Instead of manually customizing everything, you can choose one of the provided styles. You can see available styles with plt.style.available. We can set the 'Solarize_Light2' style with the same graph as drawn above and instead get:

plt.style.use('Solarize_Light2')
../../_images/example_Solarize_Light2.png

You can also manually control the styles of individual plot elements via the drawer class. All accept dictionaries of keyword-values pairs for matplotlib object components. Acceptable keywords differ based on what’s being drawn. For example, you cannot pass "fontsize" to the dictionary controlling how to format a rectangle. For the control-type gates CNOT and ctrl the options dictionary can only contain 'linewidth', 'color', or 'zorder' keys.

This example demonstrates the different ways you can format the individual elements:

wire_options = {"color": "indigo", "linewidth": 4}
drawer = MPLDrawer(n_wires=2, n_layers=4, wire_options=wire_options)

label_options = {"fontsize": "x-large", 'color': 'indigo'}
drawer.label(["0", "a"], text_options=label_options)

box_options = {'facecolor': 'lightcoral', 'edgecolor': 'maroon', 'linewidth': 5}
text_options = {'fontsize': 'xx-large', 'color': 'maroon'}
drawer.box_gate(layer=0, wires=0, text="Z", box_options=box_options, text_options=text_options)

swap_options = {'linewidth': 4, 'color': 'darkgreen'}
drawer.SWAP(layer=1, wires=(0, 1), options=swap_options)

ctrl_options = {'linewidth': 4, 'color': 'teal'}
drawer.CNOT(layer=2, wires=(0, 1), options=ctrl_options)
drawer.ctrl(layer=3, wires=(0, 1), options=ctrl_options)


measure_box = {'facecolor': 'white', 'edgecolor': 'indigo'}
measure_lines = {'edgecolor': 'indigo', 'facecolor': 'plum', 'linewidth': 2}
for wire in range(2):
    drawer.measure(layer=4, wires=wire, box_options=measure_box, lines_options=measure_lines)

drawer.fig.suptitle('My Circuit', fontsize='xx-large')
../../_images/example_formatted.png

Positioning

Each gate takes arguments in order of layer followed by wires. These translate to x and y coordinates in the graph. Layer number (x) increases as you go right, and wire number (y) increases as you go down; the y-axis is inverted. You can pass non-integer values to either keyword. If you have a long label, the gate can span multiple layers and have extra width:

drawer = MPLDrawer(2, 2)
drawer.box_gate(layer=0, wires=1, text="X")
drawer.box_gate(layer=1, wires=1, text="Y")

# Gate between two layers
drawer.box_gate(layer=0.5, wires=0, text="Big Gate", extra_width=0.5)
../../_images/float_layer.png

ax

Matplotlib axes

fig

Matplotlib figure

ax

Matplotlib axes

fig

Matplotlib figure

CNOT(layer, wires[, options])

Draws a CNOT gate.

SWAP(layer, wires[, options])

Draws a SWAP gate

box_gate(layer, wires[, text, box_options, …])

Draws a box and adds label text to its center.

ctrl(layer, wires[, wires_target, …])

Add an arbitrary number of control wires

label(labels[, text_options])

Label each wire.

measure(layer, wires[, box_options, …])

Draw a Measurement graphic at designated layer, wire combination.

CNOT(layer, wires, options=None)[source]

Draws a CNOT gate.

Parameters
  • layer (int) – layer to draw in

  • wires (Union[int, Iterable[int]]) – wires to use. Last wire is the target.

Keyword Arguments

options=None – Matplotlib options. The only supported keys are 'color', 'linewidth', and 'zorder'.

Example

drawer = MPLDrawer(n_wires=2, n_layers=2)

drawer.CNOT(0, (0, 1))

options = {'color': 'indigo', 'linewidth': 4}
drawer.CNOT(1, (1, 0), options=options)
../../_images/cnot.png
SWAP(layer, wires, options=None)[source]

Draws a SWAP gate

Parameters
  • layer (int) – layer to draw on

  • wires (Tuple[int, int]) – two wires the SWAP acts on

Keyword Arguments

options=None (dict) – matplotlib keywords for Line2D objects

Example

drawer = MPLDrawer(n_wires=2, n_layers=1)

drawer.SWAP(0, (0, 1))
../../_images/SWAP.png

The options keyword can accept any Line2D compatible keywords in a dictionary.

drawer = MPLDrawer(n_wires=2, n_layers=1)

swap_options = {"linewidth": 2, "color": "indigo"}
drawer.SWAP(0, (0, 1), options=swap_options)
../../_images/SWAP_formatted.png
box_gate(layer, wires, text='', box_options=None, text_options=None, **kwargs)[source]

Draws a box and adds label text to its center.

Parameters
  • layer (int) – x coordinate for the box center

  • wires (Union[int, Iterable[int]]) – y locations to include inside the box. Only min and max of an Iterable affect the output

  • text (str) – string to print at the box’s center

Keyword Arguments
  • box_options=None (dict) – any matplotlib keywords for the plt.Rectangle patch

  • text_options=None (dict) – any matplotlib keywords for the text

  • extra_width (float) – extra box width

  • autosize (bool) – whether to rotate and shrink text to fit within the box

Example

drawer = MPLDrawer(n_wires=2, n_layers=1)

drawer.box_gate(layer=0, wires=(0, 1), text="CY")
../../_images/box_gates.png

This method can accept two different sets of design keywords. box_options takes Rectangle keywords , and text_options accepts Matplotlib Text keywords .

box_options = {'facecolor': 'lightcoral', 'edgecolor': 'maroon', 'linewidth': 5}
text_options = {'fontsize': 'xx-large', 'color': 'maroon'}

drawer = MPLDrawer(n_wires=2, n_layers=1)

drawer.box_gate(layer=0, wires=(0, 1), text="CY",
    box_options=box_options, text_options=text_options)
../../_images/box_gates_formatted.png

By default, text is rotated and/or shrunk to fit within the box. This behavior can be turned off with the autosize=False keyword.

drawer = MPLDrawer(n_layers=4, n_wires=2)

drawer.box_gate(layer=0, wires=0, text="A longer label")
drawer.box_gate(layer=0, wires=1, text="Label")

drawer.box_gate(layer=1, wires=(0,1), text="long multigate label")

drawer.box_gate(layer=3, wires=(0,1), text="Not autosized label", autosize=False)
../../_images/box_gates_autosized.png
ctrl(layer, wires, wires_target=None, control_values=None, options=None)[source]

Add an arbitrary number of control wires

Parameters
  • layer (int) – the layer to draw the object in

  • wires (Union[int, Iterable[int]]) – set of wires to control on

Keyword Arguments
  • wires_target=None (Union[int, Iterable[int]]) – target wires. Used to determine min and max wires for the vertical line

  • control_values=None (Union[bool, Iterable[bool]]) – for each control wire, denotes whether to control on False=0 or True=1

  • options=None (dict) – Matplotlib keywords. The only supported keys are 'color', 'linewidth', and 'zorder'.

Example

drawer = MPLDrawer(n_wires=2, n_layers=3)

drawer.ctrl(layer=0, wires=0, wires_target=1)
drawer.ctrl(layer=1, wires=(0, 1), control_values=[0, 1])

options = {'color': "indigo", 'linewidth': 4}
drawer.ctrl(layer=2, wires=(0, 1), control_values=[1, 0], options=options)
../../_images/ctrl.png
label(labels, text_options=None)[source]

Label each wire.

Parameters

labels (Iterable[str]) – Iterable of labels for the wires

Keyword Arguments

text_options (dict) – any matplotlib keywords for a text object, such as font or size

Example

drawer = MPLDrawer(n_wires=2, n_layers=1)
drawer.label(["a", "b"])
../../_images/labels.png

You can also pass any Matplotlib Text keywords as a dictionary to the text_options keyword:

drawer = MPLDrawer(n_wires=2, n_layers=1)
drawer.label(["a", "b"], text_options={"color": "indigo", "fontsize": "xx-large"})
../../_images/labels_formatted.png
measure(layer, wires, box_options=None, lines_options=None)[source]

Draw a Measurement graphic at designated layer, wire combination.

Parameters
  • layer (int) – layer to draw on

  • wires (int) – wire to draw on

Keyword Arguments
  • box_options=None (dict) – dictionary to format a matplotlib rectangle

  • lines_options=None (dict) – dictionary to format matplotlib arc and arrow

Example

drawer = MPLDrawer(n_wires=1, n_layers=1)
drawer.measure(0, 0)
../../_images/measure.png

This method accepts two different formatting dictionaries. box_options edits the rectangle while lines_options edits the arc and arrow.

drawer = MPLDrawer(n_wires=1, n_layers=1)

measure_box = {'facecolor': 'white', 'edgecolor': 'indigo'}
measure_lines = {'edgecolor': 'indigo', 'facecolor': 'plum', 'linewidth': 2}
drawer.measure(0, 0, box_options=measure_box, lines_options=measure_lines)
../../_images/measure_formatted.png