Skip to content

Commit

Permalink
Clean up text drawer compression issues (Qiskit#8588)
Browse files Browse the repository at this point in the history
* Add barrier labels to mpl and text drawers

* Release note

* Add import

* Lint

* Add barrier labels to latex drawer

* Remove utils changes

* Cleanup

* Fix merge conflict

* Lint

* Remove label property for barriers and snapshots and increase mpl label font size

* First steps

* Fix vert spacing with text between lines

* Fix low compress connections and change tests

* Add tests

* Additonal test

* Lint

* Add back test

* Release note

* Fix typo in release note

Co-authored-by: Jake Lishman <[email protected]>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
  • Loading branch information
3 people authored Sep 2, 2022
1 parent 9ddc97d commit aca01eb
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 8 deletions.
10 changes: 6 additions & 4 deletions qiskit/visualization/text.py
Original file line number Diff line number Diff line change
Expand Up @@ -867,9 +867,7 @@ def should_compress(self, top_line, bot_line):
for top, bot in zip(top_line, bot_line):
if top in ["┴", "╨"] and bot in ["┬", "╥"]:
return False
for line in (bot_line, top_line):
no_spaces = line.replace(" ", "")
if len(no_spaces) > 0 and all(c.isalpha() or c.isnumeric() for c in no_spaces):
if (top.isalnum() and bot != " ") or (bot.isalnum() and top != " "):
return False
return True

Expand Down Expand Up @@ -959,6 +957,8 @@ def merge_lines(top, bot, icod="top"):
ret += "╫"
elif topc in "║╫╬" and botc in " ":
ret += "║"
elif topc in "│┼╪" and botc in " ":
ret += "│"
elif topc == "└" and botc == "┌" and icod == "top":
ret += "├"
elif topc == "┘" and botc == "┐":
Expand Down Expand Up @@ -1518,8 +1518,10 @@ def connect_with(self, wire_char):
wire_char = "║"
if index == 0 and len(affected_bits) > 1:
affected_bit.connect(wire_char, ["bot"])
else:
elif index == len(affected_bits) - 1:
affected_bit.connect(wire_char, ["top"])
else:
affected_bit.connect(wire_char, ["bot", "top"])
else:
if index == 0:
affected_bit.connect(wire_char, ["bot"])
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
fixes:
- |
There were two bugs in the ``text`` circuit drawer that were fixed.
These appeared when ``vertical_compression`` was set to ``medium``,
which is the default. The first would sometimes cause text to overwrite
other text or gates, and the second would sometimes cause the connections
between a gate and its controls to break.
See `#8588 <https://github.com/Qiskit/qiskit-terra/issues/8588>`__.
123 changes: 119 additions & 4 deletions test/python/visualization/test_circuit_text_drawer.py
Original file line number Diff line number Diff line change
Expand Up @@ -1683,7 +1683,7 @@ def test_control_gate_label_with_cond_1_high_cregbundle(self):
str(_text_circuit_drawer(circ, vertical_compression="high", cregbundle=True)), expected
)

def test_control_gate_label_with_cond_2_med(self):
def test_control_gate_label_with_cond_2_med_space(self):
"""Control gate has a label and a conditional (on label, compression=med)
See https://github.com/Qiskit/qiskit-terra/issues/4361"""
expected = "\n".join(
Expand All @@ -1692,8 +1692,7 @@ def test_control_gate_label_with_cond_2_med(self):
"q_0: |0>┤ my h ├",
" └──┬───┘",
"q_1: |0>───■────",
" my ch ",
" ║ ",
" my║ch ",
" c: 0 ═══■════",
" 0x1 ",
]
Expand All @@ -1708,6 +1707,31 @@ def test_control_gate_label_with_cond_2_med(self):

self.assertEqual(str(_text_circuit_drawer(circ, vertical_compression="medium")), expected)

def test_control_gate_label_with_cond_2_med(self):
"""Control gate has a label and a conditional (on label, compression=med)
See https://github.com/Qiskit/qiskit-terra/issues/4361"""
expected = "\n".join(
[
" ┌──────┐ ",
"q_0: |0>──┤ my h ├─",
" └──┬───┘ ",
"q_1: |0>─────■─────",
" my ctrl-h ",
" ║ ",
" c: 0 ═════■═════",
" 0x1 ",
]
)

qr = QuantumRegister(2, "q")
cr = ClassicalRegister(1, "c")
circ = QuantumCircuit(qr, cr)
hgate = HGate(label="my h")
controlh = hgate.control(label="my ctrl-h").c_if(cr, 1)
circ.append(controlh, [1, 0])

self.assertEqual(str(_text_circuit_drawer(circ, vertical_compression="medium")), expected)

def test_control_gate_label_with_cond_2_med_cregbundle(self):
"""Control gate has a label and a conditional (on label, compression=med) with cregbundle
See https://github.com/Qiskit/qiskit-terra/issues/4361"""
Expand Down Expand Up @@ -2046,7 +2070,6 @@ def test_text_conditional_1(self):
" └─╥─┘└─╥─┘",
"c0: 0 ══■════╬══",
" 0x1 ║ ",
" ║ ",
"c1: 0 ═══════■══",
" 0x1 ",
]
Expand Down Expand Up @@ -2148,6 +2171,98 @@ def test_text_measure_with_spaces_bundle(self):
expected,
)

def test_text_barrier_med_compress_1(self):
"""Medium vertical compression avoids connection break."""
circuit = QuantumCircuit(4)
circuit.cx(1, 3)
circuit.x(1)
circuit.barrier((2, 3), label="Bar 1")

expected = "\n".join(
[
" ",
"q_0: |0>────────────",
" ┌───┐ ",
"q_1: |0>──■───┤ X ├─",
" │ └───┘ ",
" │ Bar 1 ",
"q_2: |0>──┼─────░───",
" ┌─┴─┐ ░ ",
"q_3: |0>┤ X ├───░───",
" └───┘ ░ ",
]
)

self.assertEqual(
str(_text_circuit_drawer(circuit, vertical_compression="medium", cregbundle=False)),
expected,
)

def test_text_barrier_med_compress_2(self):
"""Medium vertical compression avoids overprint."""
circuit = QuantumCircuit(4)
circuit.barrier((0, 1, 2), label="a")
circuit.cx(1, 3)
circuit.x(1)
circuit.barrier((2, 3), label="Bar 1")

expected = "\n".join(
[
" a ",
"q_0: |0>─░─────────────",
" ░ ┌───┐ ",
"q_1: |0>─░───■───┤ X ├─",
" ░ │ └───┘ ",
" ░ │ Bar 1 ",
"q_2: |0>─░───┼─────░───",
" ░ ┌─┴─┐ ░ ",
"q_3: |0>───┤ X ├───░───",
" └───┘ ░ ",
]
)

self.assertEqual(
str(_text_circuit_drawer(circuit, vertical_compression="medium", cregbundle=False)),
expected,
)

def test_text_barrier_med_compress_3(self):
"""Medium vertical compression avoids conditional connection break."""
qr = QuantumRegister(1, "qr")
qc1 = ClassicalRegister(3, "cr")
qc2 = ClassicalRegister(1, "cr2")
circuit = QuantumCircuit(qr, qc1, qc2)
circuit.x(0).c_if(qc1, 3)
circuit.x(0).c_if(qc2[0], 1)

expected = "\n".join(
[
" ┌───┐┌───┐",
" qr: |0>┤ X ├┤ X ├",
" └─╥─┘└─╥─┘",
"cr_0: 0 ══■════╬══",
" ║ ║ ",
"cr_2: 0 ══o════╬══",
" ║ ║ ",
" cr2: 0 ══╬════■══",
" ║ ",
"cr_1: 0 ══■═══════",
" 0x3 ",
]
)

self.assertEqual(
str(
_text_circuit_drawer(
circuit,
vertical_compression="medium",
wire_order=[0, 1, 3, 4, 2],
cregbundle=False,
)
),
expected,
)


class TestTextConditional(QiskitTestCase):
"""Gates with conditionals"""
Expand Down

0 comments on commit aca01eb

Please sign in to comment.