Repository: Qiskit/qiskit

Issue:
An error occurs when displaying multiple Qbits with subscript names set in QuantumRegister using the QuantumCircuit draw method
<!-- ⚠️ If you do not respect this template, your issue will be closed -->
<!-- ⚠️ Make sure to browse the opened and closed issues -->

### Information

- **Qiskit Terra version**: 0.10.0
- **Python version**: 3.7.4
- **Operating system**: Win10

### What is the current behavior?
Hi Team,

There is no problem when displaying 1Qbit with the subscript name set in QuantumRegister with the draw method of QuantumCircuit.

![image](https://user-images.githubusercontent.com/12453501/69697789-e795b900-1126-11ea-8160-5e3492f9e75d.png)

However, An error ( ParseFatalException ) occurs when displaying multiple Qbits with subscript names set in QuantumRegister using the QuantumCircuit draw method

![image](https://user-images.githubusercontent.com/12453501/69697929-478c5f80-1127-11ea-95da-e6ab6bcc8e31.png)

By the way, if {} is not added, it will be displayed as follows:

![image](https://user-images.githubusercontent.com/12453501/69698527-de0d5080-1128-11ea-8a1e-78297febaa4e.png)


### Steps to reproduce the problem
As I wrote above


### What is the expected behavior?
I would like to be able to display multiple Qbits using the QuantumCircuit draw method for the subscript name set by the user in QuantumRegister.

When displaying multiple Qbits with the QuantumCircuit draw method, a subscript of the number is added, so I would like the subscript specified by the user to be displayed even before the number


### Suggested solutions
Please let me know if there are any method at this time

Thank you.




Discussion:
Hi @kUmezawa 

Did this PR fix this issue https://github.com/Qiskit/qiskit-terra/pull/3556 ? You can check against current master.
Hi @1ucian0 , @kUmezawa . Looks like the problem still persists after the latest PR. I played around with the code a bit and came up with something for this issue. Should the labeling in the below figure suffice?
![Fixed label](https://user-images.githubusercontent.com/51048173/70366055-9fab2a80-18ba-11ea-9ec2-4082db3fc746.png)

Hi, @TharrmashasthaPV @1ucian0 . Yes, this is the label I had imagined.

Resolving patch:
diff --git a/qiskit/visualization/latex.py b/qiskit/visualization/latex.py
--- a/qiskit/visualization/latex.py
+++ b/qiskit/visualization/latex.py
@@ -212,13 +212,14 @@ def _initialize_latex_array(self, aliases=None):
                                     ": 0}"
             else:
                 if self.layout is None:
-                    self._latex[i][0] = "\\lstick{{ {}_{{{}}} : \\ket{{0}} }}".format(
+                    label = "\\lstick{{ {{{}}}_{{{}}} : \\ket{{0}} }}".format(
                         self.ordered_regs[i].register.name, self.ordered_regs[i].index)
                 else:
-                    self._latex[i][0] = "\\lstick{{({}_{{{}}})~q_{{{}}} : \\ket{{0}} }}".format(
+                    label = "\\lstick{{ {{{}}}_{{{}}}\\mapsto{{{}}} : \\ket{{0}} }}".format(
                         self.layout[self.ordered_regs[i].index].register.name,
                         self.layout[self.ordered_regs[i].index].index,
                         self.ordered_regs[i].index)
+                self._latex[i][0] = label
 
     def _get_image_depth(self):
         """Get depth information for the circuit.
@@ -558,7 +559,7 @@ def _build_latex_array(self, aliases=None):
                                 # Based on the \cds command of the qcircuit package
                                 self._latex[min(pos_1, pos_2)][column + 1] = \
                                     "*+<0em,0em>{\\hphantom{zz()}} \\POS [0,0].[%d,0]=" \
-                                    "\"e\",!C *{zz(%s)};\"e\"+ R \\qw" %\
+                                    "\"e\",!C *{zz(%s)};\"e\"+ R \\qw" % \
                                     (max(pos_1, pos_2), self.parse_params(op.op.params[0]))
                                 self._latex[max(pos_1, pos_2)][column + 1] = "\\qw"
                                 num_cols_used = 2
@@ -614,7 +615,7 @@ def _build_latex_array(self, aliases=None):
                                 # Based on the \cds command of the qcircuit package
                                 self._latex[min(pos_1, pos_2)][column + 1] = \
                                     "*+<0em,0em>{\\hphantom{zz()}} \\POS [0,0].[%d,0]=" \
-                                    "\"e\",!C *{zz(%s)};\"e\"+ R \\qw" %\
+                                    "\"e\",!C *{zz(%s)};\"e\"+ R \\qw" % \
                                     (max(pos_1, pos_2), self.parse_params(op.op.params[0]))
                                 self._latex[max(pos_1, pos_2)][column + 1] = "\\qw"
                                 num_cols_used = 2
diff --git a/qiskit/visualization/matplotlib.py b/qiskit/visualization/matplotlib.py
--- a/qiskit/visualization/matplotlib.py
+++ b/qiskit/visualization/matplotlib.py
@@ -29,6 +29,7 @@
     from matplotlib import get_backend
     from matplotlib import patches
     from matplotlib import pyplot as plt
+
     HAS_MATPLOTLIB = True
 except ImportError:
     HAS_MATPLOTLIB = False
@@ -38,7 +39,6 @@
 from qiskit import user_config
 from .tools.pi_check import pi_check
 
-
 logger = logging.getLogger(__name__)
 
 WID = 0.65
@@ -327,7 +327,7 @@ def _sidetext(self, xy, text):
         # 0.15 = the initial gap, each char means it needs to move
         # another 0.0375 over
         xp = xpos + 0.15 + (0.0375 * len(text))
-        self.ax.text(xp, ypos+HIG, text, ha='center', va='top',
+        self.ax.text(xp, ypos + HIG, text, ha='center', va='top',
                      fontsize=self._style.sfs,
                      color=self._style.tc,
                      clip_on=True,
@@ -453,21 +453,21 @@ def _tgt_qubit(self, xy, fc=None, ec=None, ac=None,
         # add '+' symbol
         self.ax.plot([xpos, xpos], [ypos - add_width * HIG,
                                     ypos + add_width * HIG],
-                     color=ac, linewidth=linewidth, zorder=PORDER_GATE+1)
+                     color=ac, linewidth=linewidth, zorder=PORDER_GATE + 1)
 
         self.ax.plot([xpos - add_width * HIG, xpos + add_width * HIG],
                      [ypos, ypos], color=ac, linewidth=linewidth,
-                     zorder=PORDER_GATE+1)
+                     zorder=PORDER_GATE + 1)
 
     def _swap(self, xy):
         xpos, ypos = xy
         color = self._style.dispcol['swap']
         self.ax.plot([xpos - 0.20 * WID, xpos + 0.20 * WID],
                      [ypos - 0.20 * WID, ypos + 0.20 * WID],
-                     color=color, linewidth=2, zorder=PORDER_LINE+1)
+                     color=color, linewidth=2, zorder=PORDER_LINE + 1)
         self.ax.plot([xpos - 0.20 * WID, xpos + 0.20 * WID],
                      [ypos + 0.20 * WID, ypos - 0.20 * WID],
-                     color=color, linewidth=2, zorder=PORDER_LINE+1)
+                     color=color, linewidth=2, zorder=PORDER_LINE + 1)
 
     def _barrier(self, config, anc):
         xys = config['coord']
@@ -533,9 +533,10 @@ def _draw_regs(self):
         for ii, reg in enumerate(self._qreg):
             if len(self._qreg) > 1:
                 if self.layout is None:
-                    label = '${name}_{{{index}}}$'.format(name=reg.register.name, index=reg.index)
+                    label = '${{{name}}}_{{{index}}}$'.format(name=reg.register.name,
+                                                              index=reg.index)
                 else:
-                    label = '$({name}_{{{index}}})\\ q_{{{physical}}}$'.format(
+                    label = '${{{name}}}_{{{index}}} \\mapsto {{{physical}}}$'.format(
                         name=self.layout[reg.index].register.name,
                         index=self.layout[reg.index].index,
                         physical=reg.index)
@@ -587,7 +588,7 @@ def _draw_regs(self):
                 idx += 1
 
         # 7 is the length of the smallest possible label
-        self.x_offset = -.5 + 0.18*(len_longest_label-7)
+        self.x_offset = -.5 + 0.18 * (len_longest_label - 7)
 
     def _draw_regs_sub(self, n_fold, feedline_l=False, feedline_r=False):
         # quantum register
@@ -598,7 +599,7 @@ def _draw_regs_sub(self, n_fold, feedline_l=False, feedline_r=False):
                 label = qreg['label']
             y = qreg['y'] - n_fold * (self._cond['n_lines'] + 1)
             self.ax.text(self.x_offset, y, label, ha='right', va='center',
-                         fontsize=1.25*self._style.fs,
+                         fontsize=1.25 * self._style.fs,
                          color=self._style.tc,
                          clip_on=True,
                          zorder=PORDER_TEXT)
@@ -619,17 +620,17 @@ def _draw_regs_sub(self, n_fold, feedline_l=False, feedline_r=False):
         for y, this_creg in this_creg_dict.items():
             # bundle
             if this_creg['val'] > 1:
-                self.ax.plot([self.x_offset+1.1, self.x_offset+1.2], [y - .1, y + .1],
+                self.ax.plot([self.x_offset + 1.1, self.x_offset + 1.2], [y - .1, y + .1],
                              color=self._style.cc,
                              zorder=PORDER_LINE)
-                self.ax.text(self.x_offset+1.0, y + .1, str(this_creg['val']), ha='left',
+                self.ax.text(self.x_offset + 1.0, y + .1, str(this_creg['val']), ha='left',
                              va='bottom',
                              fontsize=0.8 * self._style.fs,
                              color=self._style.tc,
                              clip_on=True,
                              zorder=PORDER_TEXT)
             self.ax.text(self.x_offset, y, this_creg['label'], ha='right', va='center',
-                         fontsize=1.5*self._style.fs,
+                         fontsize=1.5 * self._style.fs,
                          color=self._style.tc,
                          clip_on=True,
                          zorder=PORDER_TEXT)
@@ -697,8 +698,7 @@ def _draw_ops(self, verbose=False):
                 # if custom gate with a longer than standard name determine
                 # width
                 elif op.name not in ['barrier', 'snapshot', 'load', 'save',
-                                     'noise', 'cswap', 'swap', 'measure'] and len(
-                                         op.name) >= 4:
+                                     'noise', 'cswap', 'swap', 'measure'] and len(op.name) >= 4:
                     box_width = math.ceil(len(op.name) / 6)
 
                     # handle params/subtext longer than op names
@@ -889,7 +889,7 @@ def _draw_ops(self, verbose=False):
                             self._line(qreg_b, qreg_t,
                                        lc=self._style.dispcol['multi'])
                         else:
-                            self._line(qreg_b, qreg_t, zorder=PORDER_LINE+1)
+                            self._line(qreg_b, qreg_t, zorder=PORDER_LINE + 1)
                     # control gate
                     elif op.name in ['cy', 'ch', 'cu3', 'cu1', 'crz']:
                         disp = op.name.replace('c', '')
diff --git a/qiskit/visualization/text.py b/qiskit/visualization/text.py
--- a/qiskit/visualization/text.py
+++ b/qiskit/visualization/text.py
@@ -605,7 +605,7 @@ def wire_names(self, with_initial_value=True):
                                                  physical=''))
         else:
             for bit in self.qregs:
-                label = '({name}{index}) q{physical}' + initial_qubit_value
+                label = '{name}_{index} -> {physical} ' + initial_qubit_value
                 qubit_labels.append(label.format(name=self.layout[bit.index].register.name,
                                                  index=self.layout[bit.index].index,
                                                  physical=bit.index))


Test patch:
diff --git a/test/python/visualization/references/matplotlib_barriers_ref.png b/test/python/visualization/references/matplotlib_barriers_ref.png
Binary files a/test/python/visualization/references/matplotlib_barriers_ref.png and b/test/python/visualization/references/matplotlib_barriers_ref.png differ
diff --git a/test/python/visualization/references/matplotlib_conditional_ref.png b/test/python/visualization/references/matplotlib_conditional_ref.png
Binary files a/test/python/visualization/references/matplotlib_conditional_ref.png and b/test/python/visualization/references/matplotlib_conditional_ref.png differ
diff --git a/test/python/visualization/test_circuit_matplotlib_drawer.py b/test/python/visualization/test_circuit_matplotlib_drawer.py
--- a/test/python/visualization/test_circuit_matplotlib_drawer.py
+++ b/test/python/visualization/test_circuit_matplotlib_drawer.py
@@ -162,4 +162,4 @@ def test_conditional(self):
         ref_filename = self._get_resource_path(
             'visualization/references/matplotlib_conditional_ref.png')
 
-        self.assertImagesAreEqual(ref_filename, conditional_filename)
+        self.assertImagesAreEqual(ref_filename, conditional_filename, diff_tolerance=0.002)
diff --git a/test/python/visualization/test_circuit_text_drawer.py b/test/python/visualization/test_circuit_text_drawer.py
--- a/test/python/visualization/test_circuit_text_drawer.py
+++ b/test/python/visualization/test_circuit_text_drawer.py
@@ -1680,15 +1680,15 @@ def test_with_no_layout(self):
 
     def test_mixed_layout(self):
         """ With a mixed layout. """
-        expected = '\n'.join(["                ┌───┐",
-                              "      (v0) q0|0>┤ H ├",
-                              "                ├───┤",
-                              "(ancilla1) q1|0>┤ H ├",
-                              "                ├───┤",
-                              "(ancilla0) q2|0>┤ H ├",
-                              "                ├───┤",
-                              "      (v1) q3|0>┤ H ├",
-                              "                └───┘"])
+        expected = '\n'.join(["                  ┌───┐",
+                              "      v_0 -> 0 |0>┤ H ├",
+                              "                  ├───┤",
+                              "ancilla_1 -> 1 |0>┤ H ├",
+                              "                  ├───┤",
+                              "ancilla_0 -> 2 |0>┤ H ├",
+                              "                  ├───┤",
+                              "      v_1 -> 3 |0>┤ H ├",
+                              "                  └───┘"])
         pqr = QuantumRegister(4, 'v')
         qr = QuantumRegister(2, 'v')
         ancilla = QuantumRegister(2, 'ancilla')
@@ -1699,19 +1699,19 @@ def test_mixed_layout(self):
 
     def test_with_classical_regs(self):
         """ Involving classical registers"""
-        expected = '\n'.join(["                  ",
-                              "(qr10) q0|0>──────",
-                              "                  ",
-                              "(qr11) q1|0>──────",
-                              "            ┌─┐   ",
-                              "(qr20) q2|0>┤M├───",
-                              "            └╥┘┌─┐",
-                              "(qr21) q3|0>─╫─┤M├",
-                              "             ║ └╥┘",
-                              "    cr_0: 0 ═╩══╬═",
-                              "                ║ ",
-                              "    cr_1: 0 ════╩═",
-                              "                  "])
+        expected = '\n'.join(["                    ",
+                              "qr1_0 -> 0 |0>──────",
+                              "                    ",
+                              "qr1_1 -> 1 |0>──────",
+                              "              ┌─┐   ",
+                              "qr2_0 -> 2 |0>┤M├───",
+                              "              └╥┘┌─┐",
+                              "qr2_1 -> 3 |0>─╫─┤M├",
+                              "               ║ └╥┘",
+                              "      cr_0: 0 ═╩══╬═",
+                              "                  ║ ",
+                              "      cr_1: 0 ════╩═",
+                              "                    "])
         pqr = QuantumRegister(4, 'q')
         qr1 = QuantumRegister(2, 'qr1')
         cr = ClassicalRegister(2, 'cr')
@@ -1750,40 +1750,72 @@ def test_with_layout_but_disable(self):
     def test_after_transpile(self):
         """After transpile, the drawing should include the layout"""
         expected = '\n'.join([
-            "                  ┌──────────┐┌──────────┐┌───┐┌──────────┐┌──────────────────┐┌─┐   ",
-            "   (userqr0) q0|0>┤ U2(0,pi) ├┤ U2(0,pi) ├┤ X ├┤ U2(0,pi) ├┤ U3(pi,pi/2,pi/2) ├┤M├───",
-            "                  ├──────────┤└──────────┘└─┬─┘├──────────┤└─┬─────────────┬──┘└╥┘┌─┐",
-            "   (userqr1) q1|0>┤ U2(0,pi) ├──────────────■──┤ U2(0,pi) ├──┤ U3(pi,0,pi) ├────╫─┤M├",
-            "                  └──────────┘                 └──────────┘  └─────────────┘    ║ └╥┘",
-            "  (ancilla0) q2|0>──────────────────────────────────────────────────────────────╫──╫─",
-            "                                                                                ║  ║ ",
-            "  (ancilla1) q3|0>──────────────────────────────────────────────────────────────╫──╫─",
-            "                                                                                ║  ║ ",
-            "  (ancilla2) q4|0>──────────────────────────────────────────────────────────────╫──╫─",
-            "                                                                                ║  ║ ",
-            "  (ancilla3) q5|0>──────────────────────────────────────────────────────────────╫──╫─",
-            "                                                                                ║  ║ ",
-            "  (ancilla4) q6|0>──────────────────────────────────────────────────────────────╫──╫─",
-            "                                                                                ║  ║ ",
-            "  (ancilla5) q7|0>──────────────────────────────────────────────────────────────╫──╫─",
-            "                                                                                ║  ║ ",
-            "  (ancilla6) q8|0>──────────────────────────────────────────────────────────────╫──╫─",
-            "                                                                                ║  ║ ",
-            "  (ancilla7) q9|0>──────────────────────────────────────────────────────────────╫──╫─",
-            "                                                                                ║  ║ ",
-            " (ancilla8) q10|0>──────────────────────────────────────────────────────────────╫──╫─",
-            "                                                                                ║  ║ ",
-            " (ancilla9) q11|0>──────────────────────────────────────────────────────────────╫──╫─",
-            "                                                                                ║  ║ ",
-            "(ancilla10) q12|0>──────────────────────────────────────────────────────────────╫──╫─",
-            "                                                                                ║  ║ ",
-            "(ancilla11) q13|0>──────────────────────────────────────────────────────────────╫──╫─",
-            "                                                                                ║  ║ ",
-            "          c0_0: 0 ══════════════════════════════════════════════════════════════╩══╬═",
-            "                                                                                   ║ ",
-            "          c0_1: 0 ═════════════════════════════════════════════════════════════════╩═",
-            "                                                                                     "
-        ])
+            "                    ┌──────────┐┌──────────┐┌───┐┌──────────┐┌──────────────────┐┌─┐»",
+            "   userqr_0 -> 0 |0>┤ U2(0,pi) ├┤ U2(0,pi) ├┤ X ├┤ U2(0,pi) ├┤ U3(pi,pi/2,pi/2) ├┤M├»",
+            "                    ├──────────┤└──────────┘└─┬─┘├──────────┤└─┬─────────────┬──┘└╥┘»",
+            "   userqr_1 -> 1 |0>┤ U2(0,pi) ├──────────────■──┤ U2(0,pi) ├──┤ U3(pi,0,pi) ├────╫─»",
+            "                    └──────────┘                 └──────────┘  └─────────────┘    ║ »",
+            "  ancilla_0 -> 2 |0>──────────────────────────────────────────────────────────────╫─»",
+            "                                                                                  ║ »",
+            "  ancilla_1 -> 3 |0>──────────────────────────────────────────────────────────────╫─»",
+            "                                                                                  ║ »",
+            "  ancilla_2 -> 4 |0>──────────────────────────────────────────────────────────────╫─»",
+            "                                                                                  ║ »",
+            "  ancilla_3 -> 5 |0>──────────────────────────────────────────────────────────────╫─»",
+            "                                                                                  ║ »",
+            "  ancilla_4 -> 6 |0>──────────────────────────────────────────────────────────────╫─»",
+            "                                                                                  ║ »",
+            "  ancilla_5 -> 7 |0>──────────────────────────────────────────────────────────────╫─»",
+            "                                                                                  ║ »",
+            "  ancilla_6 -> 8 |0>──────────────────────────────────────────────────────────────╫─»",
+            "                                                                                  ║ »",
+            "  ancilla_7 -> 9 |0>──────────────────────────────────────────────────────────────╫─»",
+            "                                                                                  ║ »",
+            " ancilla_8 -> 10 |0>──────────────────────────────────────────────────────────────╫─»",
+            "                                                                                  ║ »",
+            " ancilla_9 -> 11 |0>──────────────────────────────────────────────────────────────╫─»",
+            "                                                                                  ║ »",
+            "ancilla_10 -> 12 |0>──────────────────────────────────────────────────────────────╫─»",
+            "                                                                                  ║ »",
+            "ancilla_11 -> 13 |0>──────────────────────────────────────────────────────────────╫─»",
+            "                                                                                  ║ »",
+            "            c0_0: 0 ══════════════════════════════════════════════════════════════╩═»",
+            "                                                                                    »",
+            "            c0_1: 0 ════════════════════════════════════════════════════════════════»",
+            "                                                                                    »",
+            "«                    ",
+            "«   userqr_0 -> 0 ───",
+            "«                 ┌─┐",
+            "«   userqr_1 -> 1 ┤M├",
+            "«                 └╥┘",
+            "«  ancilla_0 -> 2 ─╫─",
+            "«                  ║ ",
+            "«  ancilla_1 -> 3 ─╫─",
+            "«                  ║ ",
+            "«  ancilla_2 -> 4 ─╫─",
+            "«                  ║ ",
+            "«  ancilla_3 -> 5 ─╫─",
+            "«                  ║ ",
+            "«  ancilla_4 -> 6 ─╫─",
+            "«                  ║ ",
+            "«  ancilla_5 -> 7 ─╫─",
+            "«                  ║ ",
+            "«  ancilla_6 -> 8 ─╫─",
+            "«                  ║ ",
+            "«  ancilla_7 -> 9 ─╫─",
+            "«                  ║ ",
+            "« ancilla_8 -> 10 ─╫─",
+            "«                  ║ ",
+            "« ancilla_9 -> 11 ─╫─",
+            "«                  ║ ",
+            "«ancilla_10 -> 12 ─╫─",
+            "«                  ║ ",
+            "«ancilla_11 -> 13 ─╫─",
+            "«                  ║ ",
+            "«           c0_0: ═╬═",
+            "«                  ║ ",
+            "«           c0_1: ═╩═",
+            "«                    "])
         qr = QuantumRegister(2, 'userqr')
         cr = ClassicalRegister(2, 'c0')
         qc = QuantumCircuit(qr, cr)
@@ -1798,7 +1830,7 @@ def test_after_transpile(self):
                         [13, 12]]
         qc_result = transpile(qc, basis_gates=['u1', 'u2', 'u3', 'cx', 'id'],
                               coupling_map=coupling_map, optimization_level=0)
-        self.assertEqual(qc_result.draw(output='text', fold=200).single_string(), expected)
+        self.assertEqual(qc_result.draw(output='text', fold=86).single_string(), expected)
 
 
 if __name__ == '__main__':