Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix text overwriting end of box for empty default case in mpl drawer (backport #11366) #11482

Merged
merged 1 commit into from
Jan 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 28 additions & 15 deletions qiskit/visualization/circuit/matplotlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -778,14 +778,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 @@ -1505,7 +1512,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 @@ -1532,19 +1538,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 @@ -1554,12 +1547,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 @@ -2044,6 +2044,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