Skip to content

Commit

Permalink
Fix text overwriting end of box for empty default case in mpl drawer (#…
Browse files Browse the repository at this point in the history
…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.