Repository: Qiskit/qiskit

Issue:
Issue when MPL drawing circuits - scale issue
<!-- ⚠️ If you do not respect this template, your issue may be be closed -->
<!-- ⚠️ Make sure to browse the opened and closed issues -->

### Information

- **Qiskit Terra version**: 0.8.0 
- **Python version**: 3.7.3
- **Operating system**: OS X - Version 10.9.5

### What is the current behavior?
By default if you have large names within the circuit, some of them will be out of the resultant diagram.


### Steps to reproduce the problem
You need to put large names to the circuit elements. For example this code
https://github.com/Morcu/q-means/blob/master/visualizer.py

style = {'backgroundcolor': '#DFEAEC', 'showindex': False, 'displaycolor': {
            'id': 'red', 'meas':'#0066DA', 'h': '#00DAA7', 'u3': '#EFFF1B'} }
qc.draw(output='mpl', style=style, reverse_bits= False,filename=circuit_file)

An example of the resultant circuit
https://github.com/Morcu/q-means/blob/master/circuit-without-scale.png

### What is the expected behavior?
We think that by default the scale parameter should be set to include large name of the circuit elements.
style = {'backgroundcolor': '#DFEAEC', 'showindex': False, 'displaycolor': {
            'id': 'red', 'meas':'#0066DA', 'h': '#00DAA7', 'u3': '#EFFF1B'} }
qc.draw(output='mpl', style=style, reverse_bits= False,filename=circuit_file,scale=1.2)

The resultant circuit should be like this
https://github.com/Morcu/q-means/blob/master/circuit-with-scale.png

### Suggested solutions

By default the scale should be calculated according to the circuit larger names.

---


### What is the expected behavior?



---

### What is the expected enhancement?





Discussion:
Another example: #2779

Resolving patch:
diff --git a/qiskit/visualization/matplotlib.py b/qiskit/visualization/matplotlib.py
--- a/qiskit/visualization/matplotlib.py
+++ b/qiskit/visualization/matplotlib.py
@@ -59,7 +59,7 @@ def __init__(self, reg_num, yind, fold):
         self.__gate_placed = []
         self.gate_anchor = 0
 
-    def plot_coord(self, index, gate_width):
+    def plot_coord(self, index, gate_width, x_offset):
         h_pos = index % self.__fold + 1
         # check folding
         if self.__fold > 0:
@@ -73,7 +73,7 @@ def plot_coord(self, index, gate_width):
 
         # could have been updated, so need to store
         self.gate_anchor = index
-        return x_pos, y_pos
+        return x_pos + x_offset, y_pos
 
     def is_locatable(self, index, gate_width):
         hold = [index + i for i in range(gate_width)]
@@ -152,6 +152,8 @@ def __init__(self, qregs, cregs, ops,
         self.ax.tick_params(labelbottom=False, labeltop=False,
                             labelleft=False, labelright=False)
 
+        self.x_offset = 0
+
     def _registers(self, creg, qreg):
         self._creg = []
         for r in creg:
@@ -442,6 +444,8 @@ def draw(self, filename=None, verbose=False):
         return self.figure
 
     def _draw_regs(self):
+
+        len_longest_label = 0
         # quantum register
         for ii, reg in enumerate(self._qreg):
             if len(self._qreg) > 1:
@@ -449,6 +453,9 @@ def _draw_regs(self):
             else:
                 label = '${}$'.format(reg.reg.name)
 
+            if len(label) > len_longest_label:
+                len_longest_label = len(label)
+
             pos = -ii
             self._qreg_dict[ii] = {
                 'y': pos,
@@ -484,10 +491,15 @@ def _draw_regs(self):
                         'index': reg.index,
                         'group': reg.reg
                     }
+                if len(label) > len_longest_label:
+                    len_longest_label = len(label)
 
                 self._cond['n_lines'] += 1
                 idx += 1
 
+        # 7 is the length of the smallest possible label
+        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
         for qreg in self._qreg_dict.values():
@@ -496,12 +508,12 @@ def _draw_regs_sub(self, n_fold, feedline_l=False, feedline_r=False):
             else:
                 label = qreg['label']
             y = qreg['y'] - n_fold * (self._cond['n_lines'] + 1)
-            self.ax.text(-0.5, y, label, ha='right', va='center',
+            self.ax.text(self.x_offset, y, label, ha='right', va='center',
                          fontsize=self._style.fs,
                          color=self._style.tc,
                          clip_on=True,
                          zorder=PORDER_TEXT)
-            self._line([0, y], [self._cond['xmax'], y])
+            self._line([self.x_offset + 0.5, y], [self._cond['xmax'], y])
         # classical register
         this_creg_dict = {}
         for creg in self._creg_dict.values():
@@ -639,9 +651,11 @@ def _draw_ops(self, verbose=False):
                         q_anchors[ii].set_index(this_anc, layer_width)
 
                 # qreg coordinate
-                q_xy = [q_anchors[ii].plot_coord(this_anc, layer_width) for ii in q_idxs]
+                q_xy = [q_anchors[ii].plot_coord(this_anc, layer_width, self.x_offset)
+                        for ii in q_idxs]
                 # creg coordinate
-                c_xy = [c_anchors[ii].plot_coord(this_anc, layer_width) for ii in c_idxs]
+                c_xy = [c_anchors[ii].plot_coord(this_anc, layer_width, self.x_offset)
+                        for ii in c_idxs]
                 # bottom and top point of qreg
                 qreg_b = min(q_xy, key=lambda xy: xy[1])
                 qreg_t = max(q_xy, key=lambda xy: xy[1])
@@ -658,7 +672,7 @@ def _draw_ops(self, verbose=False):
                     param = None
                 # conditional gate
                 if op.condition:
-                    c_xy = [c_anchors[ii].plot_coord(this_anc, layer_width) for
+                    c_xy = [c_anchors[ii].plot_coord(this_anc, layer_width, self.x_offset) for
                             ii in self._creg_dict]
                     mask = 0
                     for index, cbit in enumerate(self._creg):
@@ -832,10 +846,10 @@ def _draw_ops(self, verbose=False):
         n_fold = max(0, max_anc - 1) // self._style.fold
         # window size
         if max_anc > self._style.fold > 0:
-            self._cond['xmax'] = self._style.fold + 1
+            self._cond['xmax'] = self._style.fold + 1 + self.x_offset
             self._cond['ymax'] = (n_fold + 1) * (self._cond['n_lines'] + 1) - 1
         else:
-            self._cond['xmax'] = max_anc + 1
+            self._cond['xmax'] = max_anc + 1 + self.x_offset
             self._cond['ymax'] = self._cond['n_lines']
         # add horizontal lines
         for ii in range(n_fold + 1):


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_long_name_ref.png b/test/python/visualization/references/matplotlib_long_name_ref.png
new file mode 100644
Binary files /dev/null and b/test/python/visualization/references/matplotlib_long_name_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
@@ -113,3 +113,31 @@ def test_plot_barriers(self):
         self.addCleanup(os.remove, no_barriers_filename)
 
         self.assertImagesAreEqual(filename, no_barriers_filename)
+
+    @unittest.skipIf(not visualization.HAS_MATPLOTLIB,
+                     'matplotlib not available.')
+    def test_long_name(self):
+        """Test to see that long register names can be seen completely
+        As reported in #2605
+        """
+
+        # add a register with a very long name
+        qr = QuantumRegister(4, 'veryLongQuantumRegisterName012345679')
+        # add another to make sure adjustments are made based on longest
+        qrr = QuantumRegister(1, 'q0')
+        circuit = QuantumCircuit(qr, qrr)
+
+        # check gates are shifted over accordingly
+        circuit.h(qr)
+        circuit.h(qr)
+        circuit.h(qr)
+
+        long_name_filename = self._get_resource_path('current_long_name_matplotlib_ref.png')
+        visualization.circuit_drawer(circuit, output='mpl',
+                                     filename=long_name_filename)
+        self.addCleanup(os.remove, long_name_filename)
+
+        ref_filename = self._get_resource_path(
+            'visualization/references/matplotlib_long_name_ref.png')
+
+        self.assertImagesAreEqual(ref_filename, long_name_filename)