Learn How to Customize The Appearance of Your Qiskit Circuits (with Accessibility in Mind)
By Abby Mitchell, Qiskit Developer Advocate
If you’ve ever built quantum circuits with Qiskit, chances are you’ve used the circuit drawer to print out your circuit plots in either text, LaTeX, or matplotlib format. But you may not know about the full range of customization options available to style those plots, particularly for the matplotlib plots you see across Qiskit demos.
Sure, the ability to play around with the colors and styles of your circuits isn’t Qiskit’s most noteworthy feature, but it’s one that could potentially make a big difference for those with accessibility needs, for example. If you need a larger font size, specific color-blind friendly palettes, or maybe you just really hate the particular shade of teal we use for the default X gate, this blog could be the answer to your troubles!
Let’s start with a circuit. This is a very unrealistic circuit, but it’s one that shows the majority of the different types of gates you could expect to see using the Qiskit circuit drawer:
pretty_circ.draw('mpl')
Using the positional argument 'mpl'
like this will render the default Qiskit matplotlib theme, displayed above, but you can pass a number of additional arguments to the .draw()
function to customize your output.
Useful .draw()
Parameters
There are a bunch of different parameters you can pass to the .draw()
function. We'll only cover a few of them here, but you can learn about the full range available in the Qiskit documentation
One particularly useful argument for the .draw()
function is filename
, which you can use to set a file path to a location on your machine where you would like to save an image of your circuit plot:
pretty_circ.draw("mpl", filename="path/to/my/pretty_circ.png")
There are also a few useful boolean arguments that you can change:
cregbundle
- groups the classical register lines into one line (defaultTrue
)initial_state
- displays the initial state of the qubits at the start of the wire (defaultFalse
)reverse_bits
- reverses the qubit order (defaultFalse
)
If you don’t want to use the defaults you can change them by manually setting the arguments like so.
pretty_circ.draw("mpl", cregbundle=False, initial_state=True, reverse_bits=True)
The fold
parameter comes in handy when you want to adjust how many gates get printed out per circuit row. For example, take this long circuit:
long_circ.draw("mpl")
By default, the circuit drawer will print out a maximum of 25 simple gates in one row before moving onto a new row. However, by passing an integer to the fold
parameter, you can specify how long you want each row to be:
long_circ.draw("mpl", fold=20)
Setting fold
to -1
will alter the size of the plot so that the whole circuit fits on one row, which is handy if you don't want to scroll through lots of rows. You will have to compromise on font size and readability with this option, though.
long_circ.draw("mpl", fold=-1)
Lastly, you can pass a style
argument to .draw
to customize the circuit even further. There is a lot you can do with this particular parameter, so we’ll be going into this in more detail for the rest of this blog.
Built-in Circuit Styles
The first thing to note about the the style
parameter is that Qiskit has a few out-of-the-box mpl circuit themes that can be easily accessed with a single keyword string if you need a quick change.
Let’s say you need a black and white version of your circuit (like when you really need to print your circuit homework but you’ve run out of colored ink 😱). Simply use the following:
pretty_circ.draw("mpl", style="bw")
Or if you would like your circuit output to match the color scheme you’re used to seeing in the IBM Quantum Experience, you can use the iqx
option:
pretty_circ.draw("mpl", style="iqx")
Some more detail about the style
parameter
Aside from a single string name for a particular theme, the style parameter can also take a DefaultStyle
object - a dictionary of various different style options that can be applied to our mpl circuit. By creating your own DefaultStyle
object and passing it to the .draw()
function you can personalize your circuit outputs to you heart's content.
As a pseudo-code example, you can create the DefaultStyle
object as follows and then pass it to the circuit drawer in the same way as the theme names:
my_cool_style = {
"optionA": "someOption",
"optionB": "someOtherOption"
}
pretty_circ.draw("mpl", style=my_cool_style)
We'll go through a few examples of the options you can play around with, but for full details on all the options you can adjust, check out the documentation here.
Adjust your circuit text
The simplest adjustment you can make to the text of your circuit is changing the font size for the large text you see in the gate names (default size is 13), as well as the subscripts used for e.g. the parameter labels (default size is 8):
large_font = {
"fontsize": 30,
"subfontsize": 25,
}pretty_circ.draw("mpl", style=large_font)
small_font = {
"fontsize": 10,
"subfontsize": 5,
} pretty_circ.draw("mpl", style=small_font)
If you want to use custom gate names for any of the Qiskit standard library gates, you can do so by adjusting the "displaytext"
option. This option requires a dictionary where the keys are the lower case string name of the gates you wish to change, and the values are the new text you would like to be displayed:
my_gate_names = {
"displaytext": {
# gate name : gate text to be displayed
"x": "Pauli X",
"y": "Pauli Y",
"z": "Pauli Z",
"h": "Hadamard",
"reset": "Reset",
"id": "Identity"
},
}pretty_circ.draw("mpl", style=my_gate_names)
BONUS TIP!
If you’re drawing your circuit in a jupyter notebook there are even a few emojis that are supported by the mpl output! Yes, I was procrastinating on doing my real work when I discovered this, you’re welcome 😎
emoji_style = {
"displaytext": {
"id": "😄",
"x": "😍",
"y": "😎",
"z": "❤️"
},
}pretty_circ.draw("mpl", style=emoji_style)
Fun with Colors! ❤️🧡💛💚💙💜
There are a ton of options available for adjusting the colors of your circuit plot, and we’ll break them down into 4 sections: text, gates, lines and background. Style options relating to color will accept hex color codes or standard color names.
2 useful text color options include textcolor
and gatetextcolor
:
text_colours = {
# text colour for any text not inside a box (green)
"textcolor": "#6fdc8c",
# gate text colour (magenta)
"gatetextcolor": "#9f1853",
}pretty_circ.draw("mpl", style=text_colours)
Note that gatetextcolor
only sets the gate color for custom gates with their own labels — so only my_gate
in the above example. If you want to change the colors of the standard gates you can do so using the displaycolor
object, which takes a dictionary where the keys are the lowercase string names of the gate, and the values are a list of 2 color strings. The first entry corresponds to the background color of the box, and the second corresponds to the text color.
gate_colours = {
"displaycolor": {
"x": [ # gate name
"#da1e28", # box color (red)
"#FFFFFF" # box text color (white)
],
"h": [ # gate name
"#da1e28", # box color (red)
"#FFFFFF" # box text color (white)
],
"cx": [ # gate name
"#da1e28", # box color (red)
"#FFFFFF" # box text color (white)
],
"ry": [ # gate name
"#da1e28", # box color (red)
"#FFFFFF" # box text color (white)
],
},
}pretty_circ.draw("mpl", style=gate_colours)
If you want to change the box color for your custom gates (or the rzz
gate) you can do so with the gatefacecolor
option:
pretty_circ.draw("mpl", style={"gatefacecolor": "cyan"})
When it comes to line colors, you can use the following options to adjust the qubit wires, classical wires, and barriers:
line_colours = {
"linecolor": "#da1e28", # qubit wire color (red)
"creglinecolor": "#e8daff", # creg/measure wire color (lilac)
"barrierfacecolor": "pink", # barrier background color (pink)
}pretty_circ.draw("mpl", style=line_colours)
Additionally, you can change the style of the classical register line like so:
creg_style ={
"creglinestyle": "dashdot", # set style of creg and measure line
# options: '-', '--', '-.', ':', 'None', ' ', '', 'solid', 'dashed', 'dashdot', 'dotted'
}pretty_circ.draw("mpl", style=creg_style)
Finally, changing the background of the whole plot is simple using the backgroundcolor
option:
pretty_circ.draw("mpl", style={"backgroundcolor": "pink"})
Creating Accessible Circuit Plots
If you are creating circuit plots intended to be viewed publicly, we recommend choosing your styles with accessibility in mind. When we talk about the term Web Accessibility, what we mean is the process of making the things we develop online usable for people with disabilities and visual impairments. By designing accessible tools we improve usability for all other users, as well!
There are a huge number of factors to consider when it comes to accessibility, but in the context of your circuit plots we recommend paying particular attention to font size and contrast ratios.
Font size is pretty self explanatory — wherever you can, try to use the largest possible font size to make your text easier to read for those with visual impairments.
Contrast ratio relates to the color combinations you use, particularly the color of your text in contrast to the color of the background. As you have no doubt experienced, if you put dark text on a dark background (or light text on a light background) it makes it difficult to read for fully sighted readers, and even more difficult for those with visual impairments. As a general rule of thumb, try to maximize the color contrast between your text and your background, or follow the official WCAG (Web Consortium Accessibility Guidelines) color contrast standards.
For more useful info on accessibility check out these resources:
- Color contrast checker: https://marijohannessen.github.io/color-contrast-checker/
- IBM color accessibility guidelines: https://www.ibm.com/design/language/color/#accessibility
- Introduction to Web Accessibility and W3C standards here: https://www.w3.org/WAI/fundamentals/accessibility-intro/
Thanks for reading! For more blogs like this, please subscribe to the Qiskit Medium!