Repository: Qiskit/qiskit

Issue:
Consistent gates order in visualizations (and DAG?)
<!-- ⚠️ If you do not respect this template, your issue will be closed -->
<!-- ⚠️ Make sure to browse the opened and closed issues to confirm this idea does not exist. -->

### What is the expected enhancement?

As a spin-off from #1617 (thanks @Exferro!) , during that PR it was detected that the same `QuantumCircuit` produces different visualizations between Python [3.5](https://github.com/Qiskit/qiskit-terra/blob/73d47fd924edd948aee51b648b15d06211a17a20/test/python/tools/visualization/references/3.5/deep/mpl.png) and [3.6/3.7](https://github.com/Qiskit/qiskit-terra/blob/73d47fd924edd948aee51b648b15d06211a17a20/test/python/tools/visualization/references/3.6/deep/mpl.png) - the order in which `measure`s are drawn is different.

Digging a bit deeper, it seems it might be a mixture of two issues:
* the order of the instructions in the circuit (`circuit.data`) is not preserved in the final visualization
* potentially, there might be some `dict` vs `OrderedDict` issue involved (based on the example at #1617 producing the _same_ result in 3.6/3.7, and a different one in 3.5) - this is not confirmed.

### Desired behaviour

Ideally, we should be able to at least guarantee a "consistent" order (same visualization is produced regardless of Python version), and hopefully one that respects the original instruction order.

### Proposed solution

The main flow when producing a visualization is through [`_get_instructions()`](
https://github.com/Qiskit/qiskit-terra/blob/179290f082a9c4b905402db8a60fe7bb899f79e8/qiskit/tools/visualization/_utils.py#L68), which in turn ends up invoking [`node_nums_in_topological_order()`](https://github.com/Qiskit/qiskit-terra/blob/179290f082a9c4b905402db8a60fe7bb899f79e8/qiskit/dagcircuit/_dagcircuit.py#L984). A possible solution might involve ensuring that the topological sorting always return the same solution, for example "tagging" or adding extra information to the DAG for allowing it to restore the order in which gates were added to the circuit (@ajavadia can ellaborate into the idea).

## Good first contribution!

I am actually tagging this as `good first contribution`, as I believe is an interesting change to explore both the circuits/dags and the visualization sides of Terra - and with a cool end result!  If somebody is interested, please ping us by replying to this issue :tada: 






Discussion:
As an example, the following circuit:
```
  qr = QuantumRegister(2, name='qr')
  cr = ClassicalRegister(2, name='cr')
  circuit = QuantumCircuit(qr, cr)

  circuit.x(qr[0])
  circuit.measure(qr, cr)
  ```
  has the following instructions in `circuit,data`:
  ```
  [<qiskit.extensions.standard.x.XGate object at 0x7f7333d1fef0>,
   <qiskit.circuit.measure.Measure object at 0x7f73305ebfd0>,
   <qiskit.circuit.measure.Measure object at 0x7f732a7c5630>]
  ```
  and produces the following output (ie. the order of the boxes):
  ```
              ┌───┐┌─┐
  qr_0: |0>───┤ X ├┤M├
           ┌─┐└───┘└╥┘
  qr_1: |0>┤M├──────╫─
           └╥┘      ║
   cr_0: 0 ═╬═══════╩═
            ║
   cr_1: 0 ═╩═════════
  ```


For reference, the original circuit showing the symptons in #1617 is:
```
    qr = QuantumRegister(20, name='qr')
    cr = ClassicalRegister(20, name='cr')
    circuit = QuantumCircuit(qr, cr)

    for i in range(10):
        circuit.x(qr[i])
        circuit.h(qr[i])
        circuit.x(qr[i])

    circuit.barrier(qr)
    circuit.measure(qr, cr)
```
Hi @diego-plan9 I would like to work on this issue. I will try and familiarise myself with the visualisation code and get back to you if I have any questions!
That would be awesome, @maddy-tod , thanks! Don't hesitate indeed on pinging us as much as needed (specially as in this particular issue, part of the work is finding out the extent of problem and exploring a bit, and being able to reproduce it in your environment), and looking forward to your contribution!
So there are two issues:
1. For a given DAG, topological sort can give different orders (on python 3.5, 3.6, 3.7). I haven't checked this, so I think we need to confirm first. You can do something like:
```python
# ... build a circuit....

from qiskit.converters import circuit_to_dag
dag = circuit_to_dag(circuit)
dag.node_nums_in_topological_order()
```

2. The order is not the same as the user specified when building a circuit. This is verifiable by a simple circuit:
```
from qiskit import *
q = QuantumRegister(4)
circuit = QuantumCircuit(q)
circuit.cx(q[0], q[1])
circuit.cx(q[2], q[3])

print(circuit)
q0_0: |0>───────■──
              ┌─┴─┐
q0_1: |0>─────┤ X ├
              └───┘
q0_2: |0>──■───────
         ┌─┴─┐
q0_3: |0>┤ X ├─────
         └───┘
```

We can solve both issues by forcing an order on the DAG topological sort.
In the DAGCircuit class, we can assign more fields to the nodes, as a sort of metadata. So we can tag each node by the place of that gate in the original `circuit.data` list. Then have to force `networkx.topological_sort()` to take this into account when two nodes have equal priority. I don't know how to do this last part, but I think it should be doable.
[networkx.lexicographical_topological_sort](https://networkx.github.io/documentation/stable/reference/algorithms/generated/networkx.algorithms.dag.lexicographical_topological_sort.html) supports a key function to resolve ambiguities in topological sort order.
> 1. For a given DAG, topological sort can give different orders (on python 3.5, 3.6, 3.7). I haven't checked this, so I think we need to confirm first. You can do something like:

I have looked at this, and you are correct different Python versions give different orderings.

Resolving patch:
diff --git a/qiskit/visualization/circuit_visualization.py b/qiskit/visualization/circuit_visualization.py
--- a/qiskit/visualization/circuit_visualization.py
+++ b/qiskit/visualization/circuit_visualization.py
@@ -180,13 +180,15 @@ def circuit_drawer(circuit,
         image = _latex_circuit_drawer(circuit, scale=scale,
                                       filename=filename, style=style,
                                       plot_barriers=plot_barriers,
-                                      reverse_bits=reverse_bits)
+                                      reverse_bits=reverse_bits,
+                                      justify=justify)
     elif output == 'latex_source':
         return _generate_latex_source(circuit,
                                       filename=filename, scale=scale,
                                       style=style,
                                       plot_barriers=plot_barriers,
-                                      reverse_bits=reverse_bits)
+                                      reverse_bits=reverse_bits,
+                                      justify=justify)
     elif output == 'mpl':
         image = _matplotlib_circuit_drawer(circuit, scale=scale,
                                            filename=filename, style=style,
@@ -320,7 +322,8 @@ def _latex_circuit_drawer(circuit,
                           filename=None,
                           style=None,
                           plot_barriers=True,
-                          reverse_bits=False):
+                          reverse_bits=False,
+                          justify=None):
     """Draw a quantum circuit based on latex (Qcircuit package)
 
     Requires version >=2.6.0 of the qcircuit LaTeX package.
@@ -334,6 +337,8 @@ def _latex_circuit_drawer(circuit,
             registers for the output visualization.
         plot_barriers (bool): Enable/disable drawing barriers in the output
             circuit. Defaults to True.
+        justify (str) : `left`, `right` or `none`. Defaults to `left`. Says how
+                        the circuit should be justified.
 
     Returns:
         PIL.Image: an in-memory representation of the circuit diagram
@@ -349,7 +354,7 @@ def _latex_circuit_drawer(circuit,
         _generate_latex_source(circuit, filename=tmppath,
                                scale=scale, style=style,
                                plot_barriers=plot_barriers,
-                               reverse_bits=reverse_bits)
+                               reverse_bits=reverse_bits, justify=justify)
         image = None
         try:
 
@@ -392,7 +397,7 @@ def _latex_circuit_drawer(circuit,
 
 def _generate_latex_source(circuit, filename=None,
                            scale=0.7, style=None, reverse_bits=False,
-                           plot_barriers=True):
+                           plot_barriers=True, justify=None):
     """Convert QuantumCircuit to LaTeX string.
 
     Args:
@@ -404,12 +409,16 @@ def _generate_latex_source(circuit, filename=None,
             registers for the output visualization.
         plot_barriers (bool): Enable/disable drawing barriers in the output
             circuit. Defaults to True.
+        justify (str) : `left`, `right` or `none`. Defaults to `left`. Says how
+                        the circuit should be justified.
 
     Returns:
         str: Latex string appropriate for writing to file.
     """
-    qregs, cregs, ops = utils._get_instructions(circuit,
-                                                reverse_bits=reverse_bits)
+    qregs, cregs, ops = utils._get_layered_instructions(circuit,
+                                                        reverse_bits=reverse_bits,
+                                                        justify=justify)
+
     qcimg = _latex.QCircuitImage(qregs, cregs, ops, scale, style=style,
                                  plot_barriers=plot_barriers,
                                  reverse_bits=reverse_bits)
@@ -417,6 +426,7 @@ def _generate_latex_source(circuit, filename=None,
     if filename:
         with open(filename, 'w') as latex_file:
             latex_file.write(latex)
+
     return latex
 
 
diff --git a/qiskit/visualization/latex.py b/qiskit/visualization/latex.py
--- a/qiskit/visualization/latex.py
+++ b/qiskit/visualization/latex.py
@@ -58,7 +58,7 @@ def __init__(self, qregs, cregs, ops, scale, style=None,
                     dic = json.load(infile)
                 self._style.set_style(dic)
 
-        # compiled qobj circuit
+        # list of lists corresponding to layers of the circuit
         self.ops = ops
 
         # image scaling
@@ -180,7 +180,7 @@ def latex(self, aliases=None):
 
     def _initialize_latex_array(self, aliases=None):
         # pylint: disable=unused-argument
-        self.img_depth, self.sum_column_widths = self._get_image_depth(aliases)
+        self.img_depth, self.sum_column_widths = self._get_image_depth()
         self.sum_row_heights = self.img_width
         # choose the most compact row spacing, while not squashing them
         if self.has_box:
@@ -191,7 +191,7 @@ def _initialize_latex_array(self, aliases=None):
             self.row_separation = 1.0
         self._latex = [
             ["\\cw" if self.wire_type[self.ordered_regs[j]]
-             else "\\qw" for i in range(self.img_depth + 1)]
+             else "\\qw" for _ in range(self.img_depth + 1)]
             for j in range(self.img_width)]
         self._latex.append([" "] * (self.img_depth + 1))
         for i in range(self.img_width):
@@ -205,259 +205,50 @@ def _initialize_latex_array(self, aliases=None):
                                     str(self.ordered_regs[i][1]) + "}" + \
                                     ": \\ket{0}}"
 
-    def _get_image_depth(self, aliases=None):
+    def _get_image_depth(self):
         """Get depth information for the circuit.
 
-        Args:
-            aliases (dict): dict mapping the current qubits in the circuit to
-                new qubit names.
-
         Returns:
             int: number of columns in the circuit
             int: total size of columns in the circuit
-
-        Raises:
-            VisualizationError: if trying to draw unsupported gates
         """
-        columns = 2  # wires in the beginning and end
-        is_occupied = [False] * self.img_width
-        max_column_width = {}
-        for op in self.ops:
-            # useful information for determining row spacing
-            boxed_gates = ['u0', 'u1', 'u2', 'u3', 'x', 'y', 'z', 'h', 's',
-                           'sdg', 't', 'tdg', 'rx', 'ry', 'rz', 'ch', 'cy',
-                           'crz', 'cu3', 'id']
-            target_gates = ['cx', 'ccx']
-            if op.name in boxed_gates:
-                self.has_box = True
-            if op.name in target_gates:
-                self.has_target = True
-
-            # useful information for determining column widths and final image
-            # scaling
-            if op.name not in ['measure', 'reset', 'barrier']:
-                qarglist = op.qargs
-                if aliases is not None:
-                    qarglist = map(lambda x: aliases[x], qarglist)
-                if len(qarglist) == 1:
-                    pos_1 = self.img_regs[(qarglist[0][0],
-                                           qarglist[0][1])]
-                    if op.condition:
-                        mask = self._get_mask(op.condition[0])
-                        cl_reg = self.clbit_list[self._ffs(mask)]
-                        if_reg = cl_reg[0]
-                        pos_2 = self.img_regs[cl_reg]
-                        for i in range(pos_1, pos_2 + self.cregs[if_reg]):
-                            if is_occupied[i] is False:
-                                is_occupied[i] = True
-                            else:
-                                columns += 1
-                                is_occupied = [False] * self.img_width
-                                for j in range(pos_1, pos_2 + 1):
-                                    is_occupied[j] = True
-                                break
-                    else:
-                        if is_occupied[pos_1] is False:
-                            is_occupied[pos_1] = True
-                        else:
-                            columns += 1
-                            is_occupied = [False] * self.img_width
-                            is_occupied[pos_1] = True
-                elif len(qarglist) == 2:
-                    pos_1 = self.img_regs[(qarglist[0][0], qarglist[0][1])]
-                    pos_2 = self.img_regs[(qarglist[1][0], qarglist[1][1])]
 
-                    if op.condition:
-                        mask = self._get_mask(op.condition[0])
-                        cl_reg = self.clbit_list[self._ffs(mask)]
-                        if_reg = cl_reg[0]
-                        pos_3 = self.img_regs[(if_reg, 0)]
-                        if pos_1 > pos_2:
-                            for i in range(pos_2, pos_3 + self.cregs[if_reg]):
-                                if is_occupied[i] is False:
-                                    is_occupied[i] = True
-                                else:
-                                    columns += 1
-                                    is_occupied = [False] * self.img_width
-                                    for j in range(pos_2, pos_3 + 1):
-                                        is_occupied[j] = True
-                                    break
-                        else:
-                            for i in range(pos_1, pos_3 + self.cregs[if_reg]):
-                                if is_occupied[i] is False:
-                                    is_occupied[i] = True
-                                else:
-                                    columns += 1
-                                    is_occupied = [False] * self.img_width
-                                    for j in range(pos_1, pos_3 + 1):
-                                        is_occupied[j] = True
-                                    break
-                        # symetric gates have angle labels
-                        if op.name in ['cu1']:
-                            columns += 1
-                            is_occupied = [False] * self.img_width
-                            is_occupied[max(pos_1, pos_2)] = True
-                    else:
-                        temp = [pos_1, pos_2]
-                        temp.sort(key=int)
-                        top = temp[0]
-                        bottom = temp[1]
-
-                        for i in range(top, bottom + 1):
-                            if is_occupied[i] is False:
-                                is_occupied[i] = True
-                            else:
-                                columns += 1
-                                is_occupied = [False] * self.img_width
-                                for j in range(top, bottom + 1):
-                                    is_occupied[j] = True
-                                break
-                        # symetric gates have angle labels
-                        if op.name in ['cu1']:
-                            columns += 1
-                            is_occupied = [False] * self.img_width
-                            is_occupied[top] = True
-
-                elif len(qarglist) == 3:
-                    pos_1 = self.img_regs[(qarglist[0][0], qarglist[0][1])]
-                    pos_2 = self.img_regs[(qarglist[1][0], qarglist[1][1])]
-                    pos_3 = self.img_regs[(qarglist[2][0], qarglist[2][1])]
+        max_column_widths = []
 
-                    if op.condition:
-                        mask = self._get_mask(op.condition[0])
-                        cl_reg = self.clbit_list[self._ffs(mask)]
-                        if_reg = cl_reg[0]
-                        pos_4 = self.img_regs[(if_reg, 0)]
-
-                        temp = [pos_1, pos_2, pos_3, pos_4]
-                        temp.sort(key=int)
-                        top = temp[0]
-                        bottom = temp[2]
-
-                        for i in range(top, pos_4 + 1):
-                            if is_occupied[i] is False:
-                                is_occupied[i] = True
-                            else:
-                                columns += 1
-                                is_occupied = [False] * self.img_width
-                                for j in range(top, pos_4 + 1):
-                                    is_occupied[j] = True
-                                break
-                    else:
-                        temp = [pos_1, pos_2, pos_3]
-                        temp.sort(key=int)
-                        top = temp[0]
-                        bottom = temp[2]
-
-                        for i in range(top, bottom + 1):
-                            if is_occupied[i] is False:
-                                is_occupied[i] = True
-                            else:
-                                columns += 1
-                                is_occupied = [False] * self.img_width
-                                for j in range(top, bottom + 1):
-                                    is_occupied[j] = True
-                                break
-
-                elif len(qarglist) > 3:
-                    for i in range(0, len(qarglist)):
-                        pos = self.img_regs[(qarglist[i][0], qarglist[i][1])]
-                        if is_occupied[int(pos)] is False:
-                            is_occupied[int(pos)] = True
-                        else:
-                            columns += 1
-                            is_occupied = [False] * self.img_width
-                            for j in range(0, len(qarglist)):
-                                pos = self.img_regs[(qarglist[j][0],
-                                                     qarglist[j][1])]
-                                is_occupied[int(pos)] = True
-                            break
-
-                # update current column width
+        for layer in self.ops:
+
+            # store the max width for the layer
+            current_max = 0
+
+            for op in layer:
+
+                # update current op width
                 arg_str_len = 0
+
+                # the wide gates
                 for arg in op.op.params:
                     arg_str = re.sub(r'[-+]?\d*\.\d{2,}|\d{2,}',
                                      _truncate_float, str(arg))
                     arg_str_len += len(arg_str)
-                if columns not in max_column_width:
-                    max_column_width[columns] = 0
-                max_column_width[columns] = max(arg_str_len,
-                                                max_column_width[columns])
-            elif op.name == "measure":
-                if len(op.cargs) != 1 or len(op.qargs) != 1:
-                    raise exceptions.VisualizationError("bad operation record")
-                if op.condition:
-                    raise exceptions.VisualizationError(
-                        'conditional measures currently not supported.')
-                qname, qindex = op.qargs[0]
-                cname, cindex = op.cargs[0]
-                if aliases:
-                    newq = aliases[(qname, qindex)]
-                    qname = newq[0]
-                    qindex = newq[1]
-                pos_1 = self.img_regs[(qname, qindex)]
-                pos_2 = self.img_regs[(cname, cindex)]
-                temp = [pos_1, pos_2]
-                temp.sort(key=int)
-                [pos_1, pos_2] = temp
-                for i in range(pos_1, pos_2 + 1):
-                    if is_occupied[i] is False:
-                        is_occupied[i] = True
-                    else:
-                        columns += 1
-                        is_occupied = [False] * self.img_width
-                        for j in range(pos_1, pos_2 + 1):
-                            is_occupied[j] = True
-                        break
-                # update current column width
-                if columns not in max_column_width:
-                    max_column_width[columns] = 0
-            elif op.name == "reset":
-                if 'conditional' in op and op.condition:
-                    raise exceptions.VisualizationError(
-                        'conditional reset currently not supported.')
-                qname, qindex = op.qargs[0]
-                if aliases:
-                    newq = aliases[(qname, qindex)]
-                    qname = newq[0]
-                    qindex = newq[1]
-                pos_1 = self.img_regs[(qname, qindex)]
-                if is_occupied[pos_1] is False:
-                    is_occupied[pos_1] = True
-                else:
-                    columns += 1
-                    is_occupied = [False] * self.img_width
-                    is_occupied[pos_1] = True
-            elif op.name in ["barrier", 'snapshot', 'load', 'save',
-                             'noise']:
-                if self.plot_barriers:
-                    qarglist = op.qargs
-                    indexes = [self._get_qubit_index(x) for x in qarglist]
-                    start_bit = self.qubit_list[min(indexes)]
-                    if aliases is not None:
-                        qarglist = map(lambda x: aliases[x], qarglist)
-                    start = self.img_regs[start_bit]
-                    span = len(op.qargs) - 1
-                    for i in range(start, start + span + 1):
-                        if is_occupied[i] is False:
-                            is_occupied[i] = True
-                        else:
-                            columns += 1
-                            is_occupied = [False] * self.img_width
-                            for j in range(start, start + span + 1):
-                                is_occupied[j] = True
-                            break
-                    # update current column width
-                    if columns not in max_column_width:
-                        max_column_width[columns] = 0
-            else:
-                raise exceptions.VisualizationError("bad node data")
+
+                # the width of the column is the max of all the gates in the column
+                current_max = max(arg_str_len, current_max)
+
+            max_column_widths.append(current_max)
+
+        # wires in the beginning and end
+        columns = 2
+        # each layer is one column
+        columns += len(self.ops)
+
         # every 3 characters is roughly one extra 'unit' of width in the cell
         # the gate name is 1 extra 'unit'
         # the qubit/cbit labels plus initial states is 2 more
         # the wires poking out at the ends is 2 more
-        sum_column_widths = sum(1 + v / 3 for v in max_column_width.values())
-        return columns + 1, math.ceil(sum_column_widths) + 4
+        sum_column_widths = sum(1 + v / 3 for v in max_column_widths)
+
+        # could be a fraction so ceil
+        return columns, math.ceil(sum_column_widths) + 4
 
     def _get_beamer_page(self):
         """Get height, width & scale attributes for the beamer page.
@@ -508,7 +299,6 @@ def _build_latex_array(self, aliases=None):
         We will deduce the register names and sizes from aliases.
         """
         columns = 1
-        is_occupied = [False] * self.img_width
 
         # Rename qregs if necessary
         if aliases:
@@ -521,499 +311,409 @@ def _build_latex_array(self, aliases=None):
         else:
             qregdata = self.qregs
 
-        for current_op in self.ops:
-            if current_op.condition:
-                mask = self._get_mask(current_op.condition[0])
-                cl_reg = self.clbit_list[self._ffs(mask)]
-                if_reg = cl_reg[0]
-                pos_2 = self.img_regs[cl_reg]
-                if_value = format(current_op.condition[1],
-                                  'b').zfill(self.cregs[if_reg])[::-1]
-            if current_op.name not in ['measure', 'barrier', 'snapshot', 'load',
-                                       'save', 'noise']:
-                nm = current_op.name
-                qarglist = current_op.qargs
-                if aliases is not None:
-                    qarglist = map(lambda x: aliases[x], qarglist)
-                if len(qarglist) == 1:
-                    pos_1 = self.img_regs[(qarglist[0][0],
-                                           qarglist[0][1])]
-                    if current_op.condition:
-                        mask = self._get_mask(current_op.condition[0])
-                        cl_reg = self.clbit_list[self._ffs(mask)]
-                        if_reg = cl_reg[0]
-                        pos_2 = self.img_regs[cl_reg]
-                        for i in range(pos_1, pos_2 + self.cregs[if_reg]):
-                            if is_occupied[i] is False:
-                                is_occupied[i] = True
-                            else:
-                                columns += 1
-                                is_occupied = [False] * self.img_width
-                                for j in range(pos_1, pos_2 + 1):
-                                    is_occupied[j] = True
-                                break
-
-                        if nm == "x":
-                            self._latex[pos_1][columns] = "\\gate{X}"
-                        elif nm == "y":
-                            self._latex[pos_1][columns] = "\\gate{Y}"
-                        elif nm == "z":
-                            self._latex[pos_1][columns] = "\\gate{Z}"
-                        elif nm == "h":
-                            self._latex[pos_1][columns] = "\\gate{H}"
-                        elif nm == "id":
-                            self._latex[pos_1][columns] = "\\gate{Id}"
-                        elif nm == "s":
-                            self._latex[pos_1][columns] = "\\gate{S}"
-                        elif nm == "sdg":
-                            self._latex[pos_1][columns] = "\\gate{S^\\dag}"
-                        elif nm == "t":
-                            self._latex[pos_1][columns] = "\\gate{T}"
-                        elif nm == "tdg":
-                            self._latex[pos_1][columns] = "\\gate{T^\\dag}"
-                        elif nm == "u0":
-                            self._latex[pos_1][columns] = "\\gate{U_0(%s)}" % (
-                                current_op.op.params[0])
-                        elif nm == "u1":
-                            self._latex[pos_1][columns] = "\\gate{U_1(%s)}" % (
-                                current_op["op"].params[0])
-                        elif nm == "u2":
-                            self._latex[pos_1][columns] = \
-                                "\\gate{U_2\\left(%s,%s\\right)}" % (
-                                    current_op["op"].params[0], current_op["op"].params[1])
-                        elif nm == "u3":
-                            self._latex[pos_1][columns] = ("\\gate{U_3(%s,%s,%s)}" % (
-                                current_op.op.params[0],
-                                current_op.op.params[1],
-                                current_op.op.params[2]))
-                        elif nm == "rx":
-                            self._latex[pos_1][columns] = "\\gate{R_x(%s)}" % (
-                                current_op.op.params[0])
-                        elif nm == "ry":
-                            self._latex[pos_1][columns] = "\\gate{R_y(%s)}" % (
-                                current_op.op.params[0])
-                        elif nm == "rz":
-                            self._latex[pos_1][columns] = "\\gate{R_z(%s)}" % (
-                                current_op.op.params[0])
-                        else:
-                            self._latex[pos_1][columns] = "\\gate{%s}" % nm
-
-                        gap = pos_2 - pos_1
-                        for i in range(self.cregs[if_reg]):
-                            if if_value[i] == '1':
-                                self._latex[pos_2 + i][columns] = \
-                                    "\\control \\cw \\cwx[-" + str(gap) + "]"
-                                gap = 1
+        for column, layer in enumerate(self.ops, 1):
+            for op in layer:
+                if op.condition:
+                    mask = self._get_mask(op.condition[0])
+                    cl_reg = self.clbit_list[self._ffs(mask)]
+                    if_reg = cl_reg[0]
+                    pos_2 = self.img_regs[cl_reg]
+                    if_value = format(op.condition[1],
+                                      'b').zfill(self.cregs[if_reg])[::-1]
+                if op.name not in ['measure', 'barrier', 'snapshot', 'load',
+                                   'save', 'noise']:
+                    nm = op.name
+                    qarglist = op.qargs
+                    if aliases is not None:
+                        qarglist = map(lambda x: aliases[x], qarglist)
+                    if len(qarglist) == 1:
+                        pos_1 = self.img_regs[(qarglist[0][0],
+                                               qarglist[0][1])]
+
+                        if op.condition:
+                            mask = self._get_mask(op.condition[0])
+                            cl_reg = self.clbit_list[self._ffs(mask)]
+                            if_reg = cl_reg[0]
+                            pos_2 = self.img_regs[cl_reg]
+
+                            if nm == "x":
+                                self._latex[pos_1][column] = "\\gate{X}"
+                            elif nm == "y":
+                                self._latex[pos_1][column] = "\\gate{Y}"
+                            elif nm == "z":
+                                self._latex[pos_1][column] = "\\gate{Z}"
+                            elif nm == "h":
+                                self._latex[pos_1][column] = "\\gate{H}"
+                            elif nm == "s":
+                                self._latex[pos_1][column] = "\\gate{S}"
+                            elif nm == "sdg":
+                                self._latex[pos_1][column] = "\\gate{S^\\dag}"
+                            elif nm == "t":
+                                self._latex[pos_1][column] = "\\gate{T}"
+                            elif nm == "tdg":
+                                self._latex[pos_1][column] = "\\gate{T^\\dag}"
+                            elif nm == "u0":
+                                self._latex[pos_1][column] = "\\gate{U_0(%s)}" % (
+                                    op.op.params[0])
+                            elif nm == "u1":
+                                self._latex[pos_1][column] = "\\gate{U_1(%s)}" % (
+                                    op.op.params[0])
+                            elif nm == "u2":
+                                self._latex[pos_1][column] = \
+                                    "\\gate{U_2\\left(%s,%s\\right)}" % (
+                                        op.op.params[0], op.op.params[1])
+                            elif nm == "u3":
+                                self._latex[pos_1][column] = ("\\gate{U_3(%s,%s,%s)}" % (
+                                    op.op.params[0],
+                                    op.op.params[1],
+                                    op.op.params[2]))
+                            elif nm == "rx":
+                                self._latex[pos_1][column] = "\\gate{R_x(%s)}" % (
+                                    op.op.params[0])
+                            elif nm == "ry":
+                                self._latex[pos_1][column] = "\\gate{R_y(%s)}" % (
+                                    op.op.params[0])
+                            elif nm == "rz":
+                                self._latex[pos_1][column] = "\\gate{R_z(%s)}" % (
+                                    op.op.params[0])
                             else:
-                                self._latex[pos_2 + i][columns] = \
-                                    "\\controlo \\cw \\cwx[-" + str(gap) + "]"
-                                gap = 1
+                                self._latex[pos_1][columns] = "\\gate{%s}" % nm
+
+                            gap = pos_2 - pos_1
+                            for i in range(self.cregs[if_reg]):
+                                if if_value[i] == '1':
+                                    self._latex[pos_2 + i][column] = \
+                                        "\\control \\cw \\cwx[-" + str(gap) + "]"
+                                    gap = 1
+                                else:
+                                    self._latex[pos_2 + i][column] = \
+                                        "\\controlo \\cw \\cwx[-" + str(gap) + "]"
+                                    gap = 1
 
-                    else:
-                        if not is_occupied[pos_1]:
-                            is_occupied[pos_1] = True
-                        else:
-                            columns += 1
-                            is_occupied = [False] * self.img_width
-                            is_occupied[pos_1] = True
-
-                        if nm == "x":
-                            self._latex[pos_1][columns] = "\\gate{X}"
-                        elif nm == "y":
-                            self._latex[pos_1][columns] = "\\gate{Y}"
-                        elif nm == "z":
-                            self._latex[pos_1][columns] = "\\gate{Z}"
-                        elif nm == "h":
-                            self._latex[pos_1][columns] = "\\gate{H}"
-                        elif nm == "id":
-                            self._latex[pos_1][columns] = "\\gate{Id}"
-                        elif nm == "s":
-                            self._latex[pos_1][columns] = "\\gate{S}"
-                        elif nm == "sdg":
-                            self._latex[pos_1][columns] = "\\gate{S^\\dag}"
-                        elif nm == "t":
-                            self._latex[pos_1][columns] = "\\gate{T}"
-                        elif nm == "tdg":
-                            self._latex[pos_1][columns] = "\\gate{T^\\dag}"
-                        elif nm == "u0":
-                            self._latex[pos_1][columns] = "\\gate{U_0(%s)}" % (
-                                current_op.op.params[0])
-                        elif nm == "u1":
-                            self._latex[pos_1][columns] = "\\gate{U_1(%s)}" % (
-                                current_op.op.params[0])
-                        elif nm == "u2":
-                            self._latex[pos_1][columns] = \
-                                "\\gate{U_2\\left(%s,%s\\right)}" % (
-                                    current_op.op.params[0], current_op.op.params[1])
-                        elif nm == "u3":
-                            self._latex[pos_1][columns] = ("\\gate{U_3(%s,%s,%s)}" % (
-                                current_op.op.params[0],
-                                current_op.op.params[1],
-                                current_op.op.params[2]))
-                        elif nm == "rx":
-                            self._latex[pos_1][columns] = "\\gate{R_x(%s)}" % (
-                                current_op.op.params[0])
-                        elif nm == "ry":
-                            self._latex[pos_1][columns] = "\\gate{R_y(%s)}" % (
-                                current_op.op.params[0])
-                        elif nm == "rz":
-                            self._latex[pos_1][columns] = "\\gate{R_z(%s)}" % (
-                                current_op.op.params[0])
-                        elif nm == "reset":
-                            self._latex[pos_1][columns] = (
-                                "\\push{\\rule{.6em}{0em}\\ket{0}\\"
-                                "rule{.2em}{0em}} \\qw")
                         else:
-                            self._latex[pos_1][columns] = "\\gate{%s}" % nm
-
-                elif len(qarglist) == 2:
-                    pos_1 = self.img_regs[(qarglist[0][0], qarglist[0][1])]
-                    pos_2 = self.img_regs[(qarglist[1][0], qarglist[1][1])]
-
-                    if current_op.condition:
-                        pos_3 = self.img_regs[(if_reg, 0)]
-                        temp = [pos_1, pos_2, pos_3]
-                        temp.sort(key=int)
-                        top = temp[0]
-                        bottom = temp[1]
-
-                        for i in range(top, pos_3 + 1):
-                            if is_occupied[i] is False:
-                                is_occupied[i] = True
+                            if nm == "x":
+                                self._latex[pos_1][column] = "\\gate{X}"
+                            elif nm == "y":
+                                self._latex[pos_1][column] = "\\gate{Y}"
+                            elif nm == "z":
+                                self._latex[pos_1][column] = "\\gate{Z}"
+                            elif nm == "h":
+                                self._latex[pos_1][column] = "\\gate{H}"
+                            elif nm == "s":
+                                self._latex[pos_1][column] = "\\gate{S}"
+                            elif nm == "sdg":
+                                self._latex[pos_1][column] = "\\gate{S^\\dag}"
+                            elif nm == "t":
+                                self._latex[pos_1][column] = "\\gate{T}"
+                            elif nm == "tdg":
+                                self._latex[pos_1][column] = "\\gate{T^\\dag}"
+                            elif nm == "u0":
+                                self._latex[pos_1][column] = "\\gate{U_0(%s)}" % (
+                                    op.op.params[0])
+                            elif nm == "u1":
+                                self._latex[pos_1][column] = "\\gate{U_1(%s)}" % (
+                                    op.op.params[0])
+                            elif nm == "u2":
+                                self._latex[pos_1][column] = \
+                                    "\\gate{U_2\\left(%s,%s\\right)}" % (
+                                        op.op.params[0], op.op.params[1])
+                            elif nm == "u3":
+                                self._latex[pos_1][column] = ("\\gate{U_3(%s,%s,%s)}" % (
+                                    op.op.params[0],
+                                    op.op.params[1],
+                                    op.op.params[2]))
+                            elif nm == "rx":
+                                self._latex[pos_1][column] = "\\gate{R_x(%s)}" % (
+                                    op.op.params[0])
+                            elif nm == "ry":
+                                self._latex[pos_1][column] = "\\gate{R_y(%s)}" % (
+                                    op.op.params[0])
+                            elif nm == "rz":
+                                self._latex[pos_1][column] = "\\gate{R_z(%s)}" % (
+                                    op.op.params[0])
+                            elif nm == "reset":
+                                self._latex[pos_1][column] = (
+                                    "\\push{\\rule{.6em}{0em}\\ket{0}\\"
+                                    "rule{.2em}{0em}} \\qw")
                             else:
-                                columns += 1
-                                is_occupied = [False] * self.img_width
-                                for j in range(top, pos_3 + 1):
-                                    is_occupied[j] = True
-                                break
-                        # symetric gates have angle labels
-                        if current_op.name == 'cu1':
-                            columns += 1
-                            is_occupied = [False] * self.img_width
-                            is_occupied[top] = True
-
-                        gap = pos_3 - bottom
-                        for i in range(self.cregs[if_reg]):
-                            if if_value[i] == '1':
-                                self._latex[pos_3 + i][columns] = \
-                                    "\\control \\cw \\cwx[-" + str(gap) + "]"
-                                gap = 1
-                            else:
-                                self._latex[pos_3 + i][columns] = \
-                                    "\\controlo \\cw \\cwx[-" + str(gap) + "]"
-                                gap = 1
-
-                        if nm == "cx":
-                            self._latex[pos_1][columns] = \
-                                "\\ctrl{" + str(pos_2 - pos_1) + "}"
-                            self._latex[pos_2][columns] = "\\targ"
-                        elif nm == "cz":
-                            self._latex[pos_1][columns] = \
-                                "\\ctrl{" + str(pos_2 - pos_1) + "}"
-                            self._latex[pos_2][columns] = "\\control\\qw"
-                        elif nm == "cy":
-                            self._latex[pos_1][columns] = \
-                                "\\ctrl{" + str(pos_2 - pos_1) + "}"
-                            self._latex[pos_2][columns] = "\\gate{Y}"
-                        elif nm == "ch":
-                            self._latex[pos_1][columns] = \
-                                "\\ctrl{" + str(pos_2 - pos_1) + "}"
-                            self._latex[pos_2][columns] = "\\gate{H}"
-                        elif nm == "swap":
-                            self._latex[pos_1][columns] = "\\qswap"
-                            self._latex[pos_2][columns] = \
-                                "\\qswap \\qwx[" + str(pos_1 - pos_2) + "]"
-                        elif nm == "crz":
-                            self._latex[pos_1][columns] = \
-                                "\\ctrl{" + str(pos_2 - pos_1) + "}"
-                            self._latex[pos_2][columns] = \
-                                "\\gate{R_z(%s)}" % (current_op.op.params[0])
-                        elif nm == "cu1":
-                            self._latex[pos_1][columns - 1] = "\\ctrl{" + str(
-                                pos_2 - pos_1) + "}"
-                            self._latex[pos_2][columns - 1] = "\\control\\qw"
-                            self._latex[min(pos_1, pos_2)][columns] = \
-                                "\\dstick{%s}\\qw" % (current_op.op.params[0])
-                            self._latex[max(pos_1, pos_2)][columns] = "\\qw"
-                        elif nm == "cu3":
-                            self._latex[pos_1][columns] = \
-                                "\\ctrl{" + str(pos_2 - pos_1) + "}"
-                            self._latex[pos_2][columns] = \
-                                "\\gate{U_3(%s,%s,%s)}" % (current_op.op.params[0],
-                                                           current_op.op.params[1],
-                                                           current_op.op.params[2])
-                    else:
-                        temp = [pos_1, pos_2]
-                        temp.sort(key=int)
-                        top = temp[0]
-                        bottom = temp[1]
-
-                        for i in range(top, bottom + 1):
-                            if is_occupied[i] is False:
-                                is_occupied[i] = True
-                            else:
-                                columns += 1
-                                is_occupied = [False] * self.img_width
-                                for j in range(top, bottom + 1):
-                                    is_occupied[j] = True
-                                break
-                        # symetric gates have angle labels
-                        if current_op.name == 'cu1':
-                            columns += 1
-                            is_occupied = [False] * self.img_width
-                            is_occupied[top] = True
-
-                        if nm == "cx":
-                            self._latex[pos_1][columns] = "\\ctrl{" + str(
-                                pos_2 - pos_1) + "}"
-                            self._latex[pos_2][columns] = "\\targ"
-                        elif nm == "cz":
-                            self._latex[pos_1][columns] = "\\ctrl{" + str(
-                                pos_2 - pos_1) + "}"
-                            self._latex[pos_2][columns] = "\\control\\qw"
-                        elif nm == "cy":
-                            self._latex[pos_1][columns] = "\\ctrl{" + str(
-                                pos_2 - pos_1) + "}"
-                            self._latex[pos_2][columns] = "\\gate{Y}"
-                        elif nm == "ch":
-                            self._latex[pos_1][columns] = "\\ctrl{" + str(
-                                pos_2 - pos_1) + "}"
-                            self._latex[pos_2][columns] = "\\gate{H}"
-                        elif nm == "swap":
-                            self._latex[pos_1][columns] = "\\qswap"
-                            self._latex[pos_2][columns] = \
-                                "\\qswap \\qwx[" + str(pos_1 - pos_2) + "]"
-                        elif nm == "crz":
-                            self._latex[pos_1][columns] = "\\ctrl{" + str(
-                                pos_2 - pos_1) + "}"
-                            self._latex[pos_2][columns] = \
-                                "\\gate{R_z(%s)}" % (current_op.op.params[0])
-                        elif nm == "cu1":
-                            self._latex[pos_1][columns - 1] = "\\ctrl{" + str(
-                                pos_2 - pos_1) + "}"
-                            self._latex[pos_2][columns - 1] = "\\control\\qw"
-                            self._latex[min(pos_1, pos_2)][columns] = \
-                                "\\dstick{%s}\\qw" % (current_op.op.params[0])
-                            self._latex[max(pos_1, pos_2)][columns] = "\\qw"
-                        elif nm == "cu3":
-                            self._latex[pos_1][columns] = "\\ctrl{" + str(
-                                pos_2 - pos_1) + "}"
-                            self._latex[pos_2][columns] = ("\\gate{U_3(%s,%s,%s)}" % (
-                                current_op.op.params[0],
-                                current_op.op.params[1],
-                                current_op.op.params[2]))
+                                self._latex[pos_1][columns] = "\\gate{%s}" % nm
+
+                    elif len(qarglist) == 2:
+                        pos_1 = self.img_regs[(qarglist[0][0], qarglist[0][1])]
+                        pos_2 = self.img_regs[(qarglist[1][0], qarglist[1][1])]
+
+                        if op.condition:
+                            pos_3 = self.img_regs[(if_reg, 0)]
+                            temp = [pos_1, pos_2, pos_3]
+                            temp.sort(key=int)
+                            bottom = temp[1]
+
+                            gap = pos_3 - bottom
+                            for i in range(self.cregs[if_reg]):
+                                if if_value[i] == '1':
+                                    self._latex[pos_3 + i][column] = \
+                                        "\\control \\cw \\cwx[-" + str(gap) + "]"
+                                    gap = 1
+                                else:
+                                    self._latex[pos_3 + i][column] = \
+                                        "\\controlo \\cw \\cwx[-" + str(gap) + "]"
+                                    gap = 1
+
+                            if nm == "cx":
+                                self._latex[pos_1][column] = \
+                                    "\\ctrl{" + str(pos_2 - pos_1) + "}"
+                                self._latex[pos_2][column] = "\\targ"
+                            elif nm == "cz":
+                                self._latex[pos_1][column] = \
+                                    "\\ctrl{" + str(pos_2 - pos_1) + "}"
+                                self._latex[pos_2][column] = "\\control\\qw"
+                            elif nm == "cy":
+                                self._latex[pos_1][column] = \
+                                    "\\ctrl{" + str(pos_2 - pos_1) + "}"
+                                self._latex[pos_2][column] = "\\gate{Y}"
+                            elif nm == "ch":
+                                self._latex[pos_1][column] = \
+                                    "\\ctrl{" + str(pos_2 - pos_1) + "}"
+                                self._latex[pos_2][column] = "\\gate{H}"
+                            elif nm == "swap":
+                                self._latex[pos_1][column] = "\\qswap"
+                                self._latex[pos_2][column] = \
+                                    "\\qswap \\qwx[" + str(pos_1 - pos_2) + "]"
+                            elif nm == "crz":
+                                self._latex[pos_1][column] = \
+                                    "\\ctrl{" + str(pos_2 - pos_1) + "}"
+                                self._latex[pos_2][column] = \
+                                    "\\gate{R_z(%s)}" % (op.op.params[0])
+                            elif nm == "cu1":
+                                self._latex[pos_1][column - 1] = "\\ctrl{" + str(
+                                    pos_2 - pos_1) + "}"
+                                self._latex[pos_2][column - 1] = "\\control\\qw"
+                                self._latex[min(pos_1, pos_2)][column] = \
+                                    "\\dstick{%s}\\qw" % (op.op.params[0])
+                                self._latex[max(pos_1, pos_2)][column] = "\\qw"
+                            elif nm == "cu3":
+                                self._latex[pos_1][column] = \
+                                    "\\ctrl{" + str(pos_2 - pos_1) + "}"
+                                self._latex[pos_2][column] = \
+                                    "\\gate{U_3(%s,%s,%s)}" % (op.op.params[0],
+                                                               op.op.params[1],
+                                                               op.op.params[2])
                         else:
-                            start_pos = min([pos_1, pos_2])
-                            stop_pos = max([pos_1, pos_2])
-                            if stop_pos - start_pos >= 2:
-                                delta = stop_pos - start_pos
-                                self._latex[start_pos][columns] = (
-                                    "\\multigate{%s}{%s}" % (delta, nm))
-                                for i_pos in range(start_pos + 1, stop_pos + 1):
-                                    self._latex[i_pos][columns] = "\\ghost{%s}" % nm
-                            else:
-                                self._latex[start_pos][columns] = (
-                                    "\\multigate{1}{%s}" % nm)
-                                self._latex[stop_pos][columns] = "\\ghost{%s}" % nm
-
-                elif len(qarglist) == 3:
-                    pos_1 = self.img_regs[(qarglist[0][0], qarglist[0][1])]
-                    pos_2 = self.img_regs[(qarglist[1][0], qarglist[1][1])]
-                    pos_3 = self.img_regs[(qarglist[2][0], qarglist[2][1])]
-
-                    if current_op.condition:
-                        pos_4 = self.img_regs[(if_reg, 0)]
-
-                        temp = [pos_1, pos_2, pos_3, pos_4]
-                        temp.sort(key=int)
-                        top = temp[0]
-                        bottom = temp[2]
-
-                        for i in range(top, pos_4 + 1):
-                            if is_occupied[i] is False:
-                                is_occupied[i] = True
+                            temp = [pos_1, pos_2]
+                            temp.sort(key=int)
+
+                            if nm == "cx":
+                                self._latex[pos_1][column] = "\\ctrl{" + str(
+                                    pos_2 - pos_1) + "}"
+                                self._latex[pos_2][column] = "\\targ"
+                            elif nm == "cz":
+                                self._latex[pos_1][column] = "\\ctrl{" + str(
+                                    pos_2 - pos_1) + "}"
+                                self._latex[pos_2][column] = "\\control\\qw"
+                            elif nm == "cy":
+                                self._latex[pos_1][column] = "\\ctrl{" + str(
+                                    pos_2 - pos_1) + "}"
+                                self._latex[pos_2][column] = "\\gate{Y}"
+                            elif nm == "ch":
+                                self._latex[pos_1][column] = "\\ctrl{" + str(
+                                    pos_2 - pos_1) + "}"
+                                self._latex[pos_2][column] = "\\gate{H}"
+                            elif nm == "swap":
+                                self._latex[pos_1][column] = "\\qswap"
+                                self._latex[pos_2][column] = \
+                                    "\\qswap \\qwx[" + str(pos_1 - pos_2) + "]"
+                            elif nm == "crz":
+                                self._latex[pos_1][column] = "\\ctrl{" + str(
+                                    pos_2 - pos_1) + "}"
+                                self._latex[pos_2][column] = \
+                                    "\\gate{R_z(%s)}" % (op.op.params[0])
+                            elif nm == "cu1":
+                                self._latex[pos_1][column - 1] = "\\ctrl{" + str(
+                                    pos_2 - pos_1) + "}"
+                                self._latex[pos_2][column - 1] = "\\control\\qw"
+                                self._latex[min(pos_1, pos_2)][column] = \
+                                    "\\dstick{%s}\\qw" % (op.op.params[0])
+                                self._latex[max(pos_1, pos_2)][column] = "\\qw"
+                            elif nm == "cu3":
+                                self._latex[pos_1][column] = "\\ctrl{" + str(
+                                    pos_2 - pos_1) + "}"
+                                self._latex[pos_2][column] = ("\\gate{U_3(%s,%s,%s)}" % (
+                                    op.op.params[0],
+                                    op.op.params[1],
+                                    op.op.params[2]))
                             else:
-                                columns += 1
-                                is_occupied = [False] * self.img_width
-                                for j in range(top, pos_4 + 1):
-                                    is_occupied[j] = True
-                                break
-
-                        prev_column = [x[columns - 1] for x in self._latex]
-                        for item, prev_entry in enumerate(prev_column):
-                            if 'barrier' in prev_entry:
-                                span = re.search('barrier{(.*)}', prev_entry)
-                                if span and any(i in temp for i in range(
-                                        item, int(span.group(1)))):
-                                    self._latex[item][columns - 1] = \
-                                        prev_entry.replace(
-                                            '\\barrier{',
-                                            '\\barrier[-0.65em]{')
-
-                        gap = pos_4 - bottom
-                        for i in range(self.cregs[if_reg]):
-                            if if_value[i] == '1':
-                                self._latex[pos_4 + i][columns] = \
-                                    "\\control \\cw \\cwx[-" + str(gap) + "]"
-                                gap = 1
-                            else:
-                                self._latex[pos_4 + i][columns] = \
-                                    "\\controlo \\cw \\cwx[-" + str(gap) + "]"
-                                gap = 1
-
-                        if nm == "ccx":
-                            self._latex[pos_1][columns] = "\\ctrl{" + str(
-                                pos_2 - pos_1) + "}"
-                            self._latex[pos_2][columns] = "\\ctrl{" + str(
-                                pos_3 - pos_2) + "}"
-                            self._latex[pos_3][columns] = "\\targ"
-
-                        if nm == "cswap":
-                            self._latex[pos_1][columns] = "\\ctrl{" + str(
-                                pos_2 - pos_1) + "}"
-                            self._latex[pos_2][columns] = "\\qswap"
-                            self._latex[pos_3][columns] = \
-                                "\\qswap \\qwx[" + str(pos_2 - pos_3) + "]"
-                    else:
-                        temp = [pos_1, pos_2, pos_3]
-                        temp.sort(key=int)
-                        top = temp[0]
-                        bottom = temp[2]
-
-                        for i in range(top, bottom + 1):
-                            if is_occupied[i] is False:
-                                is_occupied[i] = True
+                                start_pos = min([pos_1, pos_2])
+                                stop_pos = max([pos_1, pos_2])
+                                if stop_pos - start_pos >= 2:
+                                    delta = stop_pos - start_pos
+                                    self._latex[start_pos][columns] = (
+                                        "\\multigate{%s}{%s}" % (delta, nm))
+                                    for i_pos in range(start_pos + 1, stop_pos + 1):
+                                        self._latex[i_pos][columns] = "\\ghost{%s}" % nm
+                                else:
+                                    self._latex[start_pos][columns] = (
+                                        "\\multigate{1}{%s}" % nm)
+                                    self._latex[stop_pos][columns] = "\\ghost{%s}" % nm
+
+                    elif len(qarglist) == 3:
+                        pos_1 = self.img_regs[(qarglist[0][0], qarglist[0][1])]
+                        pos_2 = self.img_regs[(qarglist[1][0], qarglist[1][1])]
+                        pos_3 = self.img_regs[(qarglist[2][0], qarglist[2][1])]
+
+                        if op.condition:
+                            pos_4 = self.img_regs[(if_reg, 0)]
+
+                            temp = [pos_1, pos_2, pos_3, pos_4]
+                            temp.sort(key=int)
+                            bottom = temp[2]
+
+                            prev_column = [x[column - 1] for x in self._latex]
+                            for item, prev_entry in enumerate(prev_column):
+                                if 'barrier' in prev_entry:
+                                    span = re.search('barrier{(.*)}', prev_entry)
+                                    if span and any(i in temp for i in range(
+                                            item, int(span.group(1)))):
+                                        self._latex[item][column - 1] = \
+                                            prev_entry.replace(
+                                                '\\barrier{',
+                                                '\\barrier[-0.65em]{')
+
+                            gap = pos_4 - bottom
+                            for i in range(self.cregs[if_reg]):
+                                if if_value[i] == '1':
+                                    self._latex[pos_4 + i][column] = \
+                                        "\\control \\cw \\cwx[-" + str(gap) + "]"
+                                    gap = 1
+                                else:
+                                    self._latex[pos_4 + i][column] = \
+                                        "\\controlo \\cw \\cwx[-" + str(gap) + "]"
+                                    gap = 1
+
+                            if nm == "ccx":
+                                self._latex[pos_1][column] = "\\ctrl{" + str(
+                                    pos_2 - pos_1) + "}"
+                                self._latex[pos_2][column] = "\\ctrl{" + str(
+                                    pos_3 - pos_2) + "}"
+                                self._latex[pos_3][column] = "\\targ"
+
+                            if nm == "cswap":
+                                self._latex[pos_1][column] = "\\ctrl{" + str(
+                                    pos_2 - pos_1) + "}"
+                                self._latex[pos_2][column] = "\\qswap"
+                                self._latex[pos_3][column] = \
+                                    "\\qswap \\qwx[" + str(pos_2 - pos_3) + "]"
+                        else:
+                            temp = [pos_1, pos_2, pos_3]
+                            temp.sort(key=int)
+
+                            prev_column = [x[column - 1] for x in self._latex]
+                            for item, prev_entry in enumerate(prev_column):
+                                if 'barrier' in prev_entry:
+                                    span = re.search('barrier{(.*)}', prev_entry)
+                                    if span and any(i in temp for i in range(
+                                            item, int(span.group(1)))):
+                                        self._latex[item][column - 1] = \
+                                            prev_entry.replace(
+                                                '\\barrier{',
+                                                '\\barrier[-0.65em]{')
+
+                            if nm == "ccx":
+                                self._latex[pos_1][column] = "\\ctrl{" + str(
+                                    pos_2 - pos_1) + "}"
+                                self._latex[pos_2][column] = "\\ctrl{" + str(
+                                    pos_3 - pos_2) + "}"
+                                self._latex[pos_3][column] = "\\targ"
+
+                            elif nm == "cswap":
+                                self._latex[pos_1][column] = "\\ctrl{" + str(
+                                    pos_2 - pos_1) + "}"
+                                self._latex[pos_2][column] = "\\qswap"
+                                self._latex[pos_3][column] = \
+                                    "\\qswap \\qwx[" + str(pos_2 - pos_3) + "]"
                             else:
-                                columns += 1
-                                is_occupied = [False] * self.img_width
-                                for j in range(top, bottom + 1):
-                                    is_occupied[j] = True
-                                break
+                                start_pos = min([pos_1, pos_2, pos_3])
+                                stop_pos = max([pos_1, pos_2, pos_3])
+                                if stop_pos - start_pos >= 3:
+                                    delta = stop_pos - start_pos
+                                    self._latex[start_pos][columns] = (
+                                        "\\multigate{%s}{%s}" % (delta, nm))
+                                    for i_pos in range(start_pos + 1, stop_pos + 1):
+                                        self._latex[i_pos][columns] = "\\ghost{%s}" % nm
+                                else:
+                                    self._latex[pos_1][columns] = (
+                                        "\\multigate{2}{%s}" % nm)
+                                    self._latex[pos_2][columns] = "\\ghost{%s}" % nm
+                                    self._latex[pos_3][columns] = "\\ghost{%s}" % nm
+
+                    elif len(qarglist) > 3:
+                        nbits = len(qarglist)
+                        pos_array = [self.img_regs[(qarglist[0][0],
+                                                    qarglist[0][1])]]
+                        for i in range(1, nbits):
+                            pos_array.append(self.img_regs[(qarglist[i][0],
+                                                            qarglist[i][1])])
+                        pos_start = min(pos_array)
+                        pos_stop = max(pos_array)
+                        delta = pos_stop - pos_start
+                        self._latex[pos_start][columns] = (
+                            "\\multigate{%s}{%s}" % (nbits - 1, nm))
+                        for pos in range(pos_start + 1, pos_stop + 1):
+                            self._latex[pos][columns] = "\\ghost{%s}" % nm
+
+                elif op.name == "measure":
+                    if (len(op.cargs) != 1
+                            or len(op.qargs) != 1
+                            or op.op.params):
+                        raise exceptions.VisualizationError("bad operation record")
 
-                        prev_column = [x[columns - 1] for x in self._latex]
+                    if op.condition:
+                        raise exceptions.VisualizationError(
+                            "If controlled measures currently not supported.")
+
+                    qname, qindex = op.qargs[0]
+                    cname, cindex = op.cargs[0]
+                    if aliases:
+                        newq = aliases[(qname, qindex)]
+                        qname = newq[0]
+                        qindex = newq[1]
+
+                    pos_1 = self.img_regs[(qname, qindex)]
+                    pos_2 = self.img_regs[(cname, cindex)]
+
+                    try:
+                        self._latex[pos_1][column] = "\\meter"
+                        prev_column = [x[column - 1] for x in self._latex]
                         for item, prev_entry in enumerate(prev_column):
                             if 'barrier' in prev_entry:
                                 span = re.search('barrier{(.*)}', prev_entry)
-                                if span and any(i in temp for i in range(
-                                        item, int(span.group(1)))):
-                                    self._latex[item][columns - 1] = \
+                                if span and (
+                                        item + int(span.group(1))) - pos_1 >= 0:
+                                    self._latex[item][column - 1] = \
                                         prev_entry.replace(
                                             '\\barrier{',
-                                            '\\barrier[-0.65em]{')
-
-                        if nm == "ccx":
-                            self._latex[pos_1][columns] = "\\ctrl{" + str(
-                                pos_2 - pos_1) + "}"
-                            self._latex[pos_2][columns] = "\\ctrl{" + str(
-                                pos_3 - pos_2) + "}"
-                            self._latex[pos_3][columns] = "\\targ"
-
-                        if nm == "cswap":
-                            self._latex[pos_1][columns] = "\\ctrl{" + str(
-                                pos_2 - pos_1) + "}"
-                            self._latex[pos_2][columns] = "\\qswap"
-                            self._latex[pos_3][columns] = \
-                                "\\qswap \\qwx[" + str(pos_2 - pos_3) + "]"
-                        else:
-                            start_pos = min([pos_1, pos_2, pos_3])
-                            stop_pos = max([pos_1, pos_2, pos_3])
-                            if stop_pos - start_pos >= 3:
-                                delta = stop_pos - start_pos
-                                self._latex[start_pos][columns] = (
-                                    "\\multigate{%s}{%s}" % (delta, nm))
-                                for i_pos in range(start_pos + 1, stop_pos + 1):
-                                    self._latex[i_pos][columns] = "\\ghost{%s}" % nm
-                            else:
-                                self._latex[pos_1][columns] = (
-                                    "\\multigate{2}{%s}" % nm)
-                                self._latex[pos_2][columns] = "\\ghost{%s}" % nm
-                                self._latex[pos_3][columns] = "\\ghost{%s}" % nm
-
-                elif len(qarglist) > 3:
-                    nbits = len(qarglist)
-                    pos_array = [self.img_regs[(qarglist[0][0],
-                                                qarglist[0][1])]]
-                    for i in range(1, nbits):
-                        pos_array.append(self.img_regs[(qarglist[i][0],
-                                                        qarglist[i][1])])
-                    pos_start = min(pos_array)
-                    pos_stop = max(pos_array)
-                    delta = pos_stop - pos_start
-                    self._latex[pos_start][columns] = (
-                        "\\multigate{%s}{%s}" % (nbits - 1, nm))
-                    for pos in range(pos_start + 1, pos_stop + 1):
-                        self._latex[pos][columns] = "\\ghost{%s}" % nm
-
-            elif current_op.name == "measure":
-                if (len(current_op.cargs) != 1
-                        or len(current_op.qargs) != 1
-                        or current_op.op.params):
-                    raise exceptions.VisualizationError("bad operation record")
-                if current_op.condition:
-                    raise exceptions.VisualizationError(
-                        "If controlled measures currently not supported.")
-
-                qname, qindex = current_op.qargs[0]
-                cname, cindex = current_op.cargs[0]
-                if aliases:
-                    newq = aliases[(qname, qindex)]
-                    qname = newq[0]
-                    qindex = newq[1]
-
-                pos_1 = self.img_regs[(qname, qindex)]
-                pos_2 = self.img_regs[(cname, cindex)]
-
-                for i in range(pos_1, pos_2 + 1):
-                    if is_occupied[i] is False:
-                        is_occupied[i] = True
-                    else:
-                        columns += 1
-                        is_occupied = [False] * self.img_width
-                        for j in range(pos_1, pos_2 + 1):
-                            is_occupied[j] = True
-                        break
-
-                try:
-                    self._latex[pos_1][columns] = "\\meter"
-                    prev_column = [x[columns - 1] for x in self._latex]
-                    for item, prev_entry in enumerate(prev_column):
-                        if 'barrier' in prev_entry:
-                            span = re.search('barrier{(.*)}', prev_entry)
-                            if span and (
-                                    item + int(span.group(1))) - pos_1 >= 0:
-                                self._latex[item][columns - 1] = \
-                                    prev_entry.replace(
-                                        '\\barrier{',
-                                        '\\barrier[-1.15em]{')
-
-                    self._latex[pos_2][columns] = \
-                        "\\cw \\cwx[-" + str(pos_2 - pos_1) + "]"
-                except Exception as e:
-                    raise exceptions.VisualizationError(
-                        'Error during Latex building: %s' % str(e))
-            elif current_op.name in ['barrier', 'snapshot', 'load', 'save',
-                                     'noise']:
-                if self.plot_barriers:
-                    qarglist = current_op.qargs
-                    indexes = [self._get_qubit_index(x) for x in qarglist]
-                    start_bit = self.qubit_list[min(indexes)]
-                    if aliases is not None:
-                        qarglist = map(lambda x: aliases[x], qarglist)
-                    start = self.img_regs[start_bit]
-                    span = len(current_op.qargs) - 1
-                    for i in range(start, start + span + 1):
-                        if is_occupied[i] is False:
-                            is_occupied[i] = True
-                        else:
-                            columns += 1
-                            is_occupied = [False] * self.img_width
-                            for j in range(start, start + span + 1):
-                                is_occupied[j] = True
-                            break
-                    self._latex[start][columns] = "\\qw \\barrier{" + str(
-                        span) + "}"
-            else:
-                raise exceptions.VisualizationError("bad node data")
+                                            '\\barrier[-1.15em]{')
+
+                        self._latex[pos_2][column] = \
+                            "\\cw \\cwx[-" + str(pos_2 - pos_1) + "]"
+                    except Exception as e:
+                        raise exceptions.VisualizationError(
+                            'Error during Latex building: %s' % str(e))
+
+                elif op.name in ['barrier', 'snapshot', 'load', 'save',
+                                 'noise']:
+                    if self.plot_barriers:
+                        qarglist = op.qargs
+                        indexes = [self._get_qubit_index(x) for x in qarglist]
+                        start_bit = self.qubit_list[min(indexes)]
+                        if aliases is not None:
+                            qarglist = map(lambda x: aliases[x], qarglist)
+                        start = self.img_regs[start_bit]
+                        span = len(op.qargs) - 1
+
+                        self._latex[start][column] = "\\qw \\barrier{" + str(
+                            span) + "}"
+                else:
+                    raise exceptions.VisualizationError("bad node data")
 
     def _get_qubit_index(self, qubit):
         """Get the index number for a quantum bit
@@ -1030,8 +730,7 @@ def _get_qubit_index(self, qubit):
                 qindex = i
                 break
         else:
-            raise exceptions.VisualizationError(
-                "unable to find bit for operation")
+            raise exceptions.VisualizationError("unable to find bit for operation")
         return qindex
 
     def _ffs(self, mask):
diff --git a/qiskit/visualization/utils.py b/qiskit/visualization/utils.py
--- a/qiskit/visualization/utils.py
+++ b/qiskit/visualization/utils.py
@@ -63,9 +63,9 @@ def _get_layered_instructions(circuit, reverse_bits=False, justify=None):
     Returns:
         Tuple(list,list,list): To be consumed by the visualizer directly.
     """
-
     if justify:
-        justify.lower()
+        justify = justify.lower()
+
     # default to left
     justify = justify if justify in ('right', 'none') else 'left'
 
@@ -176,41 +176,6 @@ def _get_layered_instructions(circuit, reverse_bits=False, justify=None):
     return qregs, cregs, ops
 
 
-def _get_instructions(circuit, reverse_bits=False):
-    """
-    Given a circuit, return a tuple (qregs, cregs, ops) where
-    qregs and cregs are the quantum and classical registers
-    in order (based on reverse_bits) and ops is a list
-    of DAG nodes which type is "operation".
-    Args:
-        circuit (QuantumCircuit): From where the information is extracted.
-        reverse_bits (bool): If true the order of the bits in the registers is
-            reversed.
-    Returns:
-        Tuple(list,list,list): To be consumed by the visualizer directly.
-    """
-    dag = circuit_to_dag(circuit)
-    ops = []
-    qregs = []
-    cregs = []
-
-    for node in dag.nodes_in_topological_order():
-        if node.type == 'op':
-            ops.append(node)
-
-    for qreg in dag.qregs.values():
-        qregs += [(qreg, bitno) for bitno in range(qreg.size)]
-
-    for creg in dag.cregs.values():
-        cregs += [(creg, bitno) for bitno in range(creg.size)]
-
-    if reverse_bits:
-        qregs.reverse()
-        cregs.reverse()
-
-    return qregs, cregs, ops
-
-
 def _get_gate_span(qregs, instruction):
     """Get the list of qubits drawing this gate would cover"""
 


Test patch:
diff --git a/test/python/visualization/test_visualization.py b/test/python/visualization/test_visualization.py
--- a/test/python/visualization/test_visualization.py
+++ b/test/python/visualization/test_visualization.py
@@ -180,39 +180,42 @@ def setUp(self):
         self.circuit.cx(self.qr1[1], self.qr1[0])
         self.circuit.measure(self.qr1[1], self.cr1[1])
 
-    def test_get_instructions(self):
-        """ _get_instructions without reverse_bits """
-        (qregs, cregs, ops) = utils._get_instructions(self.circuit)
-
-        exp = [('cx', [(QuantumRegister(2, 'qr1'), 0), (QuantumRegister(2, 'qr1'), 1)], []),
-               ('cx', [(QuantumRegister(2, 'qr2'), 0), (QuantumRegister(2, 'qr2'), 1)], []),
-               ('measure', [(QuantumRegister(2, 'qr1'), 0)], [(ClassicalRegister(2, 'cr1'), 0)]),
-               ('cx', [(QuantumRegister(2, 'qr1'), 1), (QuantumRegister(2, 'qr1'), 0)], []),
-               ('measure', [(QuantumRegister(2, 'qr1'), 1)], [(ClassicalRegister(2, 'cr1'), 1)]),
-               ('measure', [(QuantumRegister(2, 'qr2'), 0)], [(ClassicalRegister(2, 'cr2'), 0)]),
-               ('cx', [(QuantumRegister(2, 'qr2'), 1), (QuantumRegister(2, 'qr2'), 0)], []),
-               ('measure', [(QuantumRegister(2, 'qr2'), 1)], [(ClassicalRegister(2, 'cr2'), 1)])]
+    def test_get_layered_instructions(self):
+        """ _get_layered_instructions without reverse_bits """
+        (qregs, cregs, layered_ops) = utils._get_layered_instructions(self.circuit)
+
+        exp = [[('cx', [(QuantumRegister(2, 'qr2'), 0), (QuantumRegister(2, 'qr2'), 1)], []),
+                ('cx', [(QuantumRegister(2, 'qr1'), 0), (QuantumRegister(2, 'qr1'), 1)], [])],
+               [('measure', [(QuantumRegister(2, 'qr2'), 0)], [(ClassicalRegister(2, 'cr2'), 0)])],
+               [('measure', [(QuantumRegister(2, 'qr1'), 0)], [(ClassicalRegister(2, 'cr1'), 0)])],
+               [('cx', [(QuantumRegister(2, 'qr2'), 1), (QuantumRegister(2, 'qr2'), 0)], []),
+                ('cx', [(QuantumRegister(2, 'qr1'), 1), (QuantumRegister(2, 'qr1'), 0)], [])],
+               [('measure', [(QuantumRegister(2, 'qr2'), 1)], [(ClassicalRegister(2, 'cr2'), 1)])],
+               [('measure', [(QuantumRegister(2, 'qr1'), 1)], [(ClassicalRegister(2, 'cr1'), 1)])]
+               ]
 
         self.assertEqual([(self.qr1, 0), (self.qr1, 1), (self.qr2, 0), (self.qr2, 1)], qregs)
         self.assertEqual([(self.cr1, 0), (self.cr1, 1), (self.cr2, 0), (self.cr2, 1)], cregs)
-        self.assertEqual(exp, [(op.name, op.qargs, op.cargs) for op in ops])
-
-    def test_get_instructions_reverse_bits(self):
-        """ _get_instructions with reverse_bits=True """
-        (qregs, cregs, ops) = utils._get_instructions(self.circuit, reverse_bits=True)
-
-        exp = [('cx', [(QuantumRegister(2, 'qr1'), 0), (QuantumRegister(2, 'qr1'), 1)], []),
-               ('cx', [(QuantumRegister(2, 'qr2'), 0), (QuantumRegister(2, 'qr2'), 1)], []),
-               ('measure', [(QuantumRegister(2, 'qr1'), 0)], [(ClassicalRegister(2, 'cr1'), 0)]),
-               ('cx', [(QuantumRegister(2, 'qr1'), 1), (QuantumRegister(2, 'qr1'), 0)], []),
-               ('measure', [(QuantumRegister(2, 'qr1'), 1)], [(ClassicalRegister(2, 'cr1'), 1)]),
-               ('measure', [(QuantumRegister(2, 'qr2'), 0)], [(ClassicalRegister(2, 'cr2'), 0)]),
-               ('cx', [(QuantumRegister(2, 'qr2'), 1), (QuantumRegister(2, 'qr2'), 0)], []),
-               ('measure', [(QuantumRegister(2, 'qr2'), 1)], [(ClassicalRegister(2, 'cr2'), 1)])]
+        self.assertEqual(exp, [[(op.name, op.qargs, op.cargs) for op in ops]for ops in layered_ops])
+
+    def test_get_layered_instructions_reverse_bits(self):
+        """ _get_layered_instructions with reverse_bits=True """
+        (qregs, cregs, layered_ops) = utils._get_layered_instructions(self.circuit,
+                                                                      reverse_bits=True)
+
+        exp = [[('cx', [(QuantumRegister(2, 'qr2'), 0), (QuantumRegister(2, 'qr2'), 1)], []),
+                ('cx', [(QuantumRegister(2, 'qr1'), 0), (QuantumRegister(2, 'qr1'), 1)], [])],
+               [('measure', [(QuantumRegister(2, 'qr2'), 0)], [(ClassicalRegister(2, 'cr2'), 0)])],
+               [('measure', [(QuantumRegister(2, 'qr1'), 0)], [(ClassicalRegister(2, 'cr1'), 0)])],
+               [('cx', [(QuantumRegister(2, 'qr2'), 1), (QuantumRegister(2, 'qr2'), 0)], []),
+                ('cx', [(QuantumRegister(2, 'qr1'), 1), (QuantumRegister(2, 'qr1'), 0)], [])],
+               [('measure', [(QuantumRegister(2, 'qr2'), 1)], [(ClassicalRegister(2, 'cr2'), 1)])],
+               [('measure', [(QuantumRegister(2, 'qr1'), 1)], [(ClassicalRegister(2, 'cr1'), 1)])]
+               ]
 
         self.assertEqual([(self.qr2, 1), (self.qr2, 0), (self.qr1, 1), (self.qr1, 0)], qregs)
         self.assertEqual([(self.cr2, 1), (self.cr2, 0), (self.cr1, 1), (self.cr1, 0)], cregs)
-        self.assertEqual(exp, [(op.name, op.qargs, op.cargs) for op in ops])
+        self.assertEqual(exp, [[(op.name, op.qargs, op.cargs) for op in ops]for ops in layered_ops])
 
 
 if __name__ == '__main__':