Skip to content

Commit

Permalink
Fix text overwriting end of box for empty default case in mpl drawer (Q…
Browse files Browse the repository at this point in the history
…iskit#11366)

* Testing

* Fix case default empty

* Add reno

* Lint
  • Loading branch information
enavarro51 authored Jan 2, 2024
1 parent d565b40 commit fe2d7f9
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 15 deletions.
43 changes: 28 additions & 15 deletions qiskit/visualization/circuit/matplotlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -779,14 +779,21 @@ def _get_coords(
l_width.append(layer_widths[node][0])
node_data[node].x_index = x_index

# Special case of default case with no ops in it, need to push end
# of switch op one extra x_index
if isinstance(node.op, SwitchCaseOp):
if len(node.op.blocks[-1]) == 0:
curr_x_index += 1

# adjust the column if there have been barriers encountered, but not plotted
barrier_offset = 0
if not self._plot_barriers:
# only adjust if everything in the layer wasn't plotted
barrier_offset = (
-1 if all(getattr(nd.op, "_directive", False) for nd in layer) else 0
)
prev_x_index = curr_x_index + max(l_width) + barrier_offset - 1
max_lwidth = max(l_width) if l_width else 0
prev_x_index = curr_x_index + max_lwidth + barrier_offset - 1

return prev_x_index + 1

Expand Down Expand Up @@ -1515,7 +1522,6 @@ def _flow_op_gate(self, node, node_data, glob_data):

if_width = node_data[node].width[0] + WID
box_width = if_width

# Add the else and case widths to the if_width
for ewidth in node_data[node].width[1:]:
if ewidth > 0.0:
Expand All @@ -1542,19 +1548,6 @@ def _flow_op_gate(self, node, node_data, glob_data):
y_shift = fold_level * (glob_data["n_lines"] + 1)
end_x = xpos + box_width - x_shift

# FancyBbox allows rounded corners
box = glob_data["patches_mod"].FancyBboxPatch(
xy=(xpos - x_shift, ypos - 0.5 * HIG - y_shift),
width=box_width,
height=height,
boxstyle="round, pad=0.1",
fc="none",
ec=colors[node_data[node].nest_depth % 4],
linewidth=self._lwidth3,
zorder=PORDER_FLOW,
)
self._ax.add_patch(box)

if isinstance(node.op, IfElseOp):
flow_text = " If"
elif isinstance(node.op, WhileLoopOp):
Expand All @@ -1564,12 +1557,32 @@ def _flow_op_gate(self, node, node_data, glob_data):
elif isinstance(node.op, SwitchCaseOp):
flow_text = "Switch"

# Some spacers. op_spacer moves 'Switch' back a bit for alignment,
# expr_spacer moves the expr over to line up with 'Switch' and
# empty_default_spacer makes the switch box longer if the default
# case is empty so text doesn't run past end of box.
if isinstance(node.op, SwitchCaseOp):
op_spacer = 0.04
expr_spacer = 0.0
empty_default_spacer = 0.3 if len(node.op.blocks[-1]) == 0 else 0.0
else:
op_spacer = 0.08
expr_spacer = 0.02
empty_default_spacer = 0.0

# FancyBbox allows rounded corners
box = glob_data["patches_mod"].FancyBboxPatch(
xy=(xpos - x_shift, ypos - 0.5 * HIG - y_shift),
width=box_width + empty_default_spacer,
height=height,
boxstyle="round, pad=0.1",
fc="none",
ec=colors[node_data[node].nest_depth % 4],
linewidth=self._lwidth3,
zorder=PORDER_FLOW,
)
self._ax.add_patch(box)

# Indicate type of ControlFlowOp and if expression used, print below
self._ax.text(
xpos - x_shift - op_spacer,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
fixes:
- |
Fixed an issue in the ``mpl`` circuit drawer where the text would print beyond
the end of the box for a :class:`.SwitchCaseOp` if the default case was empty.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 28 additions & 0 deletions test/visual/mpl/circuit/test_circuit_matplotlib_drawer.py
Original file line number Diff line number Diff line change
Expand Up @@ -2052,6 +2052,34 @@ def test_switch_case_op_1_qarg(self):
)
self.assertGreaterEqual(ratio, 0.9999)

def test_switch_case_op_empty_default(self):
"""Test the SwitchCaseOp with empty default case"""
qreg = QuantumRegister(3, "q")
creg = ClassicalRegister(3, "cr")
circuit = QuantumCircuit(qreg, creg)

circuit.h([0, 1, 2])
circuit.measure([0, 1, 2], [0, 1, 2])

with circuit.switch(creg) as case:
with case(0, 1, 2):
circuit.x(0)
with case(case.DEFAULT):
pass
circuit.h(0)

fname = "switch_case_empty_default.png"
self.circuit_drawer(circuit, output="mpl", cregbundle=False, filename=fname)

ratio = VisualTestUtilities._save_diff(
self._image_path(fname),
self._reference_path(fname),
fname,
FAILURE_DIFF_DIR,
FAILURE_PREFIX,
)
self.assertGreaterEqual(ratio, 0.9999)

def test_if_with_expression(self):
"""Test the IfElseOp with an expression"""
qr = QuantumRegister(3, "qr")
Expand Down

0 comments on commit fe2d7f9

Please sign in to comment.