Repository: Qiskit/qiskit

Issue:
Matplotlib circuit drawer returns messy output
<!-- ⚠️ 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**: master
- **Python version**:
- **Operating system**: OSX

`mpl.__version__ = 3.0.3`

### What is the current behavior?
<img width="258" alt="Screen Shot 2019-03-19 at 1 50 11 PM" src="https://user-images.githubusercontent.com/1249193/54629507-17e07000-4a4e-11e9-92cb-4237de85e312.png">
<img width="832" alt="Screen Shot 2019-03-19 at 1 50 28 PM" src="https://user-images.githubusercontent.com/1249193/54629517-1c0c8d80-4a4e-11e9-91ea-48efe4c687d5.png">



### Steps to reproduce the problem
```python
import numpy as np
from qiskit import *
from qiskit.transpiler import transpile
from qiskit.tools.qi.qi import random_unitary_matrix
from qiskit.mapper import two_qubit_kak
from qiskit.mapper import CouplingMap
from qiskit.extensions.standard import SwapGate
%matplotlib inline

IBMQ.load_accounts()
backend = IBMQ.get_backend('ibmq_16_melbourne')
basis = backend.configuration().to_dict()['basis_gates']
coupling_map = CouplingMap(backend.configuration().to_dict()['coupling_map'])

from qiskit.transpiler.passes import *
from qiskit.transpiler.passes.mapping import *

pm = qiskit.transpiler.PassManager()
pm.append(Unroller(basis))
pm.append(BarrierBeforeFinalMeasurements())
pm.append(DenseLayout(coupling_map))
pm.append(StochasticSwap(coupling_map))
pm.append(Decompose(SwapGate))
pm.append(CXDirection(coupling_map))
pm.append(CXCancellation())
pm.append(Unroller(basis))
pm.append(Optimize1qGates())

def build_qv_circuit(seed, n, depth):
    """Create a quantum program containing model circuits.

    The model circuits consist of layers of Haar random
    elements of SU(4) applied between corresponding pairs
    of qubits in a random bipartition.

    name = leading name of circuits
    n = number of qubits
    depth = ideal depth of each model circuit (over SU(4))

    """
    np.random.seed(seed)
    q = QuantumRegister(n, "q")
    c = ClassicalRegister(n, "c")
    # Create measurement subcircuit
    qc = QuantumCircuit(q,c)
    # For each layer
    for j in range(depth):
        # Generate uniformly random permutation Pj of [0...n-1]
        perm = np.random.permutation(n)
        # For each pair p in Pj, generate Haar random SU(4)
        # Decompose each SU(4) into CNOT + SU(2) and add to Ci
        for k in range(int(np.floor(n/2))):
            qubits = [int(perm[2*k]), int(perm[2*k+1])]
            U = random_unitary_matrix(4)
            for gate in two_qubit_kak(U):
                i0 = qubits[gate["args"][0]]
                if gate["name"] == "cx":
                    i1 = qubits[gate["args"][1]]
                    qc.cx(q[i0], q[i1])
                elif gate["name"] == "u1":
                    qc.u1(gate["params"][2], q[i0])
                elif gate["name"] == "u2":
                    qc.u2(gate["params"][1], gate["params"][2],
                                 q[i0])
                elif gate["name"] == "u3":
                    qc.u3(gate["params"][0], gate["params"][1],
                                 gate["params"][2], q[i0])
                elif gate["name"] == "id":
                    pass  # do nothing
    #qc.measure(q,c)
    return qc

qc =  build_qv_circuit(123456, 14, 1)
comp_qc = transpile(qc, backend=backend, pass_manager=pm)
comp_qc.draw(output='mpl')
```

Note that this circuit has no `ccx` gates even though the drawing makes it look like that 

### What is the expected behavior?



### Suggested solutions





Discussion:
@nkanazawa1989 @maddy-tod Could you see this bug?
@t-imamichi yes I can and I have fixed it, I will submit a PR shortly.

Resolving patch:
diff --git a/qiskit/tools/visualization/_matplotlib.py b/qiskit/tools/visualization/_matplotlib.py
--- a/qiskit/tools/visualization/_matplotlib.py
+++ b/qiskit/tools/visualization/_matplotlib.py
@@ -49,6 +49,7 @@ def __init__(self, reg_num, yind, fold):
         self.__fold = fold
         self.__reg_num = reg_num
         self.__gate_placed = []
+        self.gate_anchor = 0
 
     def plot_coord(self, index, gate_width):
         h_pos = index % self.__fold + 1
@@ -62,6 +63,8 @@ def plot_coord(self, index, gate_width):
             x_pos = index + 1 + 0.5 * (gate_width - 1)
             y_pos = self.__yind
 
+        # could have been updated, so need to store
+        self.gate_anchor = index
         return x_pos, y_pos
 
     def is_locatable(self, index, gate_width):
@@ -455,10 +458,6 @@ def _draw_regs_sub(self, n_fold, feedline_l=False, feedline_r=False):
     def _draw_ops(self, verbose=False):
         _wide_gate = 'u2 u3 cu2 cu3'.split()
         _barriers = {'coord': [], 'group': []}
-        next_ops = self._ops.copy()
-        if next_ops:
-            next_ops.pop(0)
-        this_anc = 0
 
         #
         # generate coordinate manager
@@ -476,55 +475,38 @@ def _draw_ops(self, verbose=False):
         #
         # draw gates
         #
-        prev_width = 0
-        for layer_no, layer in enumerate(self._ops):
-
+        prev_anc = -1
+        for layer in self._ops:
             layer_width = 1
 
             for op in layer:
                 if op.name in _wide_gate:
                     layer_width = 2
 
+            this_anc = prev_anc + 1
+
             for op in layer:
 
                 _iswide = op.name in _wide_gate
                 # get qreg index
-                if op.qargs:
-                    q_idxs = []
-                    for qarg in op.qargs:
-                        for index, reg in self._qreg_dict.items():
-                            if (reg['group'] == qarg[0] and
-                                    reg['index'] == qarg[1]):
-                                q_idxs.append(index)
-                                break
-                else:
-                    q_idxs = []
+                q_idxs = []
+                for qarg in op.qargs:
+                    for index, reg in self._qreg_dict.items():
+                        if (reg['group'] == qarg[0] and
+                                reg['index'] == qarg[1]):
+                            q_idxs.append(index)
+                            break
+
                 # get creg index
-                if op.cargs:
-                    c_idxs = []
-                    for carg in op.cargs:
-                        for index, reg in self._creg_dict.items():
-                            if (reg['group'] == carg[0] and
-                                    reg['index'] == carg[1]):
-                                c_idxs.append(index)
-                                break
-                else:
-                    c_idxs = []
-
-                this_anc = layer_no + prev_width
-
-                occupied = q_idxs
-                q_list = [ii for ii in range(min(occupied),
-                                             max(occupied) + 1)]
-                locs = [q_anchors[jj].is_locatable(
-                    this_anc, layer_width) for jj in q_list]
-                if all(locs):
-                    for ii in q_list:
-                        if op.name in ['barrier', 'snapshot', 'load', 'save', 'noise'] \
-                                and not self.plot_barriers:
-                            q_anchors[ii].set_index(this_anc - 1, layer_width)
-                        else:
-                            q_anchors[ii].set_index(this_anc, layer_width)
+                c_idxs = []
+                for carg in op.cargs:
+                    for index, reg in self._creg_dict.items():
+                        if (reg['group'] == carg[0] and
+                                reg['index'] == carg[1]):
+                            c_idxs.append(index)
+                            break
+                for ii in q_idxs:
+                    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]
@@ -534,6 +516,9 @@ def _draw_ops(self, verbose=False):
                 qreg_b = min(q_xy, key=lambda xy: xy[1])
                 qreg_t = max(q_xy, key=lambda xy: xy[1])
 
+                # update index based on the value from plotting
+                this_anc = q_anchors[q_idxs[0]].gate_anchor
+
                 if verbose:
                     print(op)
 
@@ -661,7 +646,7 @@ def _draw_ops(self, verbose=False):
                     logger.critical('Invalid gate %s', op)
                     raise exceptions.VisualizationError('invalid gate {}'.format(op))
 
-            prev_width = layer_width - 1
+            prev_anc = this_anc + layer_width - 1
         #
         # adjust window size and draw horizontal lines
         #


Test patch: