qml.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
andn_wires
.
Example
drawer = qml.drawer.MPLDrawer(n_wires=5, n_layers=6) 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") drawer.box_gate(layer=1, wires=[0, 2, 3], text="U(θ)") drawer.box_gate(layer=1, wires=4, text="Z") drawer.SWAP(layer=2, wires=(3,4)) 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')
Usage Details
Matplotlib Integration
This class relies on matplotlib. As such, users can extend this class via interacting with the figure
drawer.fig
and axesdrawer.ax
objects manually. For instance, the example circuit manipulates the figure to set a title usingdrawer.fig.suptitle
. Users can save the image usingplt.savefig
or via the figure methoddrawer.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
PennyLane has inbuilt styles for controlling the appearance of the circuit drawings. All available styles can be determined by evaluating
qml.drawer.available_styles()
. Any available string can then be passed toqml.drawer.use_style
.qml.drawer.use_style('black_white')
You can also control the appearance with matplotlib’s provided tools, see the matplotlib docs . For example, we can customize
plt.rcParams
:plt.rcParams['patch.facecolor'] = 'mistyrose' plt.rcParams['patch.edgecolor'] = 'maroon' plt.rcParams['text.color'] = 'maroon' plt.rcParams['font.weight'] = 'bold' plt.rcParams['patch.linewidth'] = 4 plt.rcParams['patch.force_edgecolor'] = True plt.rcParams['lines.color'] = 'indigo' plt.rcParams['lines.linewidth'] = 5 plt.rcParams['figure.facecolor'] = 'ghostwhite'
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 gatesCNOT
andctrl
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')
Positioning
Each gate takes arguments in order of
layer
followed bywires
. These translate tox
andy
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)
Attributes
Matplotlib axes
Matplotlib figure
Default fontsize for text.
-
ax
¶ Matplotlib axes
-
fig
¶ Matplotlib figure
-
fontsize
¶ Default fontsize for text. Defaults to 14.
Methods
CNOT
(layer, wires[, control_values, 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, control_values=None, options=None)[source]¶ Draws a CNOT gate.
- Parameters
layer (int) – layer to draw in
control_values=None (Union[bool, Iterable[bool]]) – for each control wire, denotes whether to control on
False=0
orTrue=1
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)
-
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
The
options
keyword can accept any Line2D compatible keywords in a dictionary.drawer = MPLDrawer(n_wires=2, n_layers=2) drawer.SWAP(0, (0, 1)) swap_options = {"linewidth": 2, "color": "indigo"} drawer.SWAP(1, (0, 1), options=swap_options)
-
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
patchtext_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
active_wire_notches (bool) – whether or not to add notches indicating active wires. Defaults to
True
.
Example
drawer = MPLDrawer(n_wires=2, n_layers=1) drawer.box_gate(layer=0, wires=(0, 1), text="CY")
Usage Details
This method can accept two different sets of design keywords.
box_options
takes Rectangle keywords , andtext_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)
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)
-
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
orTrue=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)
-
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"])
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"})
-
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
This method accepts two different formatting dictionaries.
box_options
edits the rectangle whilelines_options
edits the arc and arrow.drawer = MPLDrawer(n_wires=2, n_layers=1) drawer.measure(layer=0, wires=0) measure_box = {'facecolor': 'white', 'edgecolor': 'indigo'} measure_lines = {'edgecolor': 'indigo', 'facecolor': 'plum', 'linewidth': 2} drawer.measure(layer=0, wires=1, box_options=measure_box, lines_options=measure_lines)