Repository: Qiskit/qiskit

Issue:
Left justify the circuit in text visualizer
<!-- ⚠️ 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?
Currently when a circuit is displayed using the text drawer each gate in a circuit sits in its own column, as shown in the following circuit.
``` 
         ┌───┐          
q1_0: |0>┤ H ├──────────
         └───┘┌───┐     
q1_1: |0>─────┤ H ├─────
              └───┘     
```
It would be better if the circuits could be left justified, so the above circuit would appear as below.
```
         ┌───┐          
q1_0: |0>┤ H ├───────
         └───┘
         ┌───┐          
q1_1: |0>┤ H ├───────
         └───┘
```
It appears that circuits are already justified like this in the matplotlib drawer.


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/tools/visualization/_circuit_visualization.py b/qiskit/tools/visualization/_circuit_visualization.py
--- a/qiskit/tools/visualization/_circuit_visualization.py
+++ b/qiskit/tools/visualization/_circuit_visualization.py
@@ -41,7 +41,8 @@ def circuit_drawer(circuit,
                    interactive=False,
                    line_length=None,
                    plot_barriers=True,
-                   reverse_bits=False):
+                   reverse_bits=False,
+                   justify=None):
     """Draw a quantum circuit to different formats (set by output parameter):
     0. text: ASCII art TextDrawing that can be printed in the console.
     1. latex: high-quality images, but heavy external software dependencies
@@ -76,6 +77,11 @@ def circuit_drawer(circuit,
             registers for the output visualization.
         plot_barriers (bool): Enable/disable drawing barriers in the output
             circuit. Defaults to True.
+        justify (string): Options are `left`, `right` or `none`, if anything
+            else is supplied it defaults to left justified. It refers to where
+            gates should be placed in the output circuit if there is an option.
+            `none` results in each gate being placed in its own column. Currently
+            only supported by text drawer.
 
     Returns:
         PIL.Image: (output `latex`) an in-memory representation of the image
@@ -168,7 +174,8 @@ def circuit_drawer(circuit,
         return _text_circuit_drawer(circuit, filename=filename,
                                     line_length=line_length,
                                     reversebits=reverse_bits,
-                                    plotbarriers=plot_barriers)
+                                    plotbarriers=plot_barriers,
+                                    justify=justify)
     elif output == 'latex':
         image = _latex_circuit_drawer(circuit, scale=scale,
                                       filename=filename, style=style,
@@ -272,7 +279,7 @@ def qx_color_scheme():
 
 
 def _text_circuit_drawer(circuit, filename=None, line_length=None, reversebits=False,
-                         plotbarriers=True):
+                         plotbarriers=True, justify=None):
     """
     Draws a circuit using ascii art.
     Args:
@@ -285,10 +292,14 @@ def _text_circuit_drawer(circuit, filename=None, line_length=None, reversebits=F
                    at all, set line_length=-1.
         reversebits (bool): Rearrange the bits in reverse order.
         plotbarriers (bool): Draws the barriers when they are there.
+        justify (str) : `left`, `right` or `none`. Defaults to `left`. Says how
+                        the circuit should be justified.
     Returns:
         TextDrawing: An instances that, when printed, draws the circuit in ascii art.
     """
-    qregs, cregs, ops = _utils._get_instructions(circuit, reversebits=reversebits)
+    qregs, cregs, ops = _utils._get_layered_instructions(circuit,
+                                                         reversebits=reversebits,
+                                                         justify=justify)
     text_drawing = _text.TextDrawing(qregs, cregs, ops)
     text_drawing.plotbarriers = plotbarriers
     text_drawing.line_length = line_length
diff --git a/qiskit/tools/visualization/_text.py b/qiskit/tools/visualization/_text.py
--- a/qiskit/tools/visualization/_text.py
+++ b/qiskit/tools/visualization/_text.py
@@ -37,6 +37,7 @@ def top(self):
             ret = ret.ljust(self.right_fill, self.top_pad)
         if self.left_fill:
             ret = ret.rjust(self.left_fill, self.top_pad)
+
         return ret
 
     @property
@@ -59,11 +60,13 @@ def bot(self):
             ret = ret.ljust(self.right_fill, self.bot_pad)
         if self.left_fill:
             ret = ret.rjust(self.left_fill, self.bot_pad)
+
         return ret
 
     @property
     def length(self):
         """ Returns the length of the element, including the box around."""
+
         return max(len(self.top), len(self.mid), len(self.bot))
 
     @length.setter
@@ -91,6 +94,7 @@ def connect(self, wire_char, where, label=None):
             where (list["top", "bot"]): Where the connector should be set.
             label (string): Some connectors have a label (see cu1, for example).
         """
+
         if 'top' in where and self.top_connector:
             self.top_connect = self.top_connector[wire_char]
 
@@ -168,6 +172,9 @@ def __init__(self):
         self.mid_content = "┤M├"
         self.bot_connect = "└╥┘"
 
+        self.top_pad = self.bot_pad = " "
+        self._mid_padding = '─'
+
 
 class MultiBox(DrawElement):
     """Elements that is draw on over multiple wires."""
@@ -321,7 +328,7 @@ class Bullet(DirectOnQuWire):
     bot:  │      │
     """
 
-    def __init__(self, top_connect=" ", bot_connect=" "):
+    def __init__(self, top_connect="", bot_connect=""):
         super().__init__('■')
         self.top_connect = top_connect
         self.bot_connect = bot_connect
@@ -403,7 +410,8 @@ def fillup_layer(names):  # pylint: disable=arguments-differ
 class TextDrawing():
     """ The text drawing"""
 
-    def __init__(self, qregs, cregs, instructions, plotbarriers=True, line_length=None):
+    def __init__(self, qregs, cregs, instructions, plotbarriers=True,
+                 line_length=None):
         self.qregs = qregs
         self.cregs = cregs
         self.instructions = instructions
@@ -433,7 +441,7 @@ def _get_clbit_labels(self):
 
     def single_string(self):
         """
-        Creates a loong string with the ascii art
+        Creates a long string with the ascii art
         Returns:
             str: The lines joined by '\n'
         """
@@ -471,14 +479,8 @@ def lines(self, line_length=None):
                 line_length, _ = get_terminal_size()
 
         noqubits = len(self.qregs)
-        layers = self.build_layers()
 
-        # TODO compress layers
-        # -| H |----------
-        # --------| H |---
-        # should be
-        # -| H |---
-        # -| H |---
+        layers = self.build_layers()
 
         if not line_length:
             line_length = self.line_length
@@ -559,7 +561,7 @@ def draw_wires(wires):
         bot_line = None
         for wire in wires:
             # TOP
-            top_line = ""
+            top_line = ''
             for instruction in wire:
                 top_line += instruction.top
 
@@ -572,7 +574,6 @@ def draw_wires(wires):
             mid_line = ""
             for instruction in wire:
                 mid_line += instruction.mid
-
             lines.append(TextDrawing.merge_lines(lines[-1], mid_line, icod="bot"))
 
             # BOT
@@ -645,6 +646,8 @@ def merge_lines(top, bot, icod="top"):
                 ret += "├"
             elif topc == '┘' and botc == "┐":
                 ret += "┤"
+            elif botc in "┐┌":
+                ret += "┬"
             else:
                 ret += botc
         return ret
@@ -661,6 +664,115 @@ def normalize_width(layer):
         for instruction in instructions:
             instruction.length = longest
 
+    def _instruction_to_gate(self, instruction, layer):
+        """ Convert an instruction into its corresponding Gate object, and establish
+        any connections it introduces between qubits"""
+
+        current_cons = []
+        connection_label = None
+
+        # add in a gate that operates over multiple qubits
+        def add_connected_gate(instruction, gates, layer, current_cons):
+            for i, gate in enumerate(gates):
+                layer.set_qubit(instruction['qargs'][i], gate)
+                actual_index = self.qregs.index(instruction['qargs'][i])
+                current_cons.append((actual_index, gate))
+
+        if instruction['name'] == 'measure':
+            gate = MeasureFrom()
+            layer.set_qubit(instruction['qargs'][0], gate)
+            layer.set_clbit(instruction['cargs'][0], MeasureTo())
+
+        elif instruction['name'] in ['barrier', 'snapshot', 'save', 'load',
+                                     'noise']:
+            # barrier
+            if not self.plotbarriers:
+                return layer, current_cons, connection_label
+
+            for qubit in instruction['qargs']:
+                layer.set_qubit(qubit, Barrier())
+
+        elif instruction['name'] == 'swap':
+            # swap
+            gates = [Ex() for _ in range(len(instruction['qargs']))]
+            add_connected_gate(instruction, gates, layer, current_cons)
+
+        elif instruction['name'] == 'cswap':
+            # cswap
+            gates = [Bullet(), Ex(), Ex()]
+            add_connected_gate(instruction, gates, layer, current_cons)
+
+        elif instruction['name'] == 'reset':
+            layer.set_qubit(instruction['qargs'][0], Reset())
+
+        elif instruction['condition'] is not None:
+            # conditional
+            cllabel = TextDrawing.label_for_conditional(instruction)
+            qulabel = TextDrawing.label_for_box(instruction)
+
+            layer.set_cl_multibox(instruction['condition'][0], cllabel, top_connect='┴')
+            layer.set_qubit(instruction['qargs'][0], BoxOnQuWire(qulabel, bot_connect='┬'))
+
+        elif instruction['name'] in ['cx', 'CX', 'ccx']:
+            # cx/ccx
+            gates = [Bullet() for _ in range(len(instruction['qargs']) - 1)]
+            gates.append(BoxOnQuWire('X'))
+            add_connected_gate(instruction, gates, layer, current_cons)
+
+        elif instruction['name'] == 'cy':
+            # cy
+            gates = [Bullet(), BoxOnQuWire('Y')]
+            add_connected_gate(instruction, gates, layer, current_cons)
+
+        elif instruction['name'] == 'cz':
+            # cz
+            gates = [Bullet(), Bullet()]
+            add_connected_gate(instruction, gates, layer, current_cons)
+
+        elif instruction['name'] == 'ch':
+            # ch
+            gates = [Bullet(), BoxOnQuWire('H')]
+            add_connected_gate(instruction, gates, layer, current_cons)
+
+        elif instruction['name'] == 'cu1':
+            # cu1
+            connection_label = TextDrawing.params_for_label(instruction)[0]
+            gates = [Bullet(), Bullet()]
+            add_connected_gate(instruction, gates, layer, current_cons)
+
+        elif instruction['name'] == 'cu3':
+            # cu3
+            params = TextDrawing.params_for_label(instruction)
+            gates = [Bullet(), BoxOnQuWire("U3(%s)" % ','.join(params))]
+            add_connected_gate(instruction, gates, layer, current_cons)
+
+        elif instruction['name'] == 'crz':
+            # crz
+            label = "Rz(%s)" % TextDrawing.params_for_label(instruction)[0]
+
+            gates = [Bullet(), BoxOnQuWire(label)]
+            add_connected_gate(instruction, gates, layer, current_cons)
+
+        elif len(instruction['qargs']) == 1 and not instruction['cargs']:
+            # unitary gate
+            layer.set_qubit(instruction['qargs'][0],
+                            BoxOnQuWire(TextDrawing.label_for_box(instruction)))
+
+        elif len(instruction['qargs']) >= 2 and not instruction['cargs']:
+            # multiple qubit gate
+            layer.set_qu_multibox(instruction['qargs'], TextDrawing.label_for_box(instruction))
+
+        else:
+            raise VisualizationError(
+                "Text visualizer does not know how to handle this instruction", instruction)
+
+        # sort into the order they were declared in
+        # this ensures that connected boxes have lines in the right direction
+        current_cons.sort(key=lambda tup: tup[0])
+        current_cons = [g for q, g in current_cons]
+
+        return layer, current_cons, connection_label
+
     def build_layers(self):
         """
         Constructs layers.
@@ -669,104 +781,18 @@ def build_layers(self):
         Raises:
             VisualizationError: When the drawing is, for some reason, impossible to be drawn.
         """
-        layers = []
 
-        layers.append(InputWire.fillup_layer(self.wire_names(with_initial_value=True)))
+        layers = [InputWire.fillup_layer(self.wire_names(with_initial_value=True))]
 
-        for instruction in self.instructions:
+        for instruction_layer in self.instructions:
             layer = Layer(self.qregs, self.cregs)
-            connector_label = None
-
-            if instruction['name'] == 'measure':
-                layer.set_qubit(instruction['qargs'][0], MeasureFrom())
-                layer.set_clbit(instruction['cargs'][0], MeasureTo())
-
-            elif instruction['name'] in ['barrier', 'snapshot', 'save', 'load',
-                                         'noise']:
-                # barrier
-                if not self.plotbarriers:
-                    continue
-
-                for qubit in instruction['qargs']:
-                    layer.set_qubit(qubit, Barrier())
-
-            elif instruction['name'] == 'swap':
-                # swap
-                for qubit in instruction['qargs']:
-                    layer.set_qubit(qubit, Ex())
-
-            elif instruction['name'] == 'cswap':
-                # cswap
-                layer.set_qubit(instruction['qargs'][0], Bullet())
-                layer.set_qubit(instruction['qargs'][1], Ex())
-                layer.set_qubit(instruction['qargs'][2], Ex())
-
-            elif instruction['name'] == 'reset':
-                layer.set_qubit(instruction['qargs'][0], Reset())
-
-            elif instruction['condition'] is not None:
-                # conditional
-                cllabel = TextDrawing.label_for_conditional(instruction)
-                qulabel = TextDrawing.label_for_box(instruction)
-
-                layer.set_cl_multibox(instruction['condition'][0], cllabel, top_connect='┴')
-                layer.set_qubit(instruction['qargs'][0], BoxOnQuWire(qulabel, bot_connect='┬'))
-
-            elif instruction['name'] in ['cx', 'CX', 'ccx']:
-                # cx/ccx
-                for qubit in [qubit for qubit in instruction['qargs'][:-1]]:
-                    layer.set_qubit(qubit, Bullet())
-                layer.set_qubit(instruction['qargs'][-1], BoxOnQuWire('X'))
-
-            elif instruction['name'] == 'cy':
-                # cy
-                layer.set_qubit(instruction['qargs'][0], Bullet())
-                layer.set_qubit(instruction['qargs'][1], BoxOnQuWire('Y'))
-
-            elif instruction['name'] == 'cz':
-                # cz
-                layer.set_qubit(instruction['qargs'][0], Bullet())
-                layer.set_qubit(instruction['qargs'][1], Bullet())
-
-            elif instruction['name'] == 'ch':
-                # ch
-                layer.set_qubit(instruction['qargs'][0], Bullet())
-                layer.set_qubit(instruction['qargs'][1], BoxOnQuWire('H'))
-
-            elif instruction['name'] == 'cu1':
-                # cu1
-                connector_label = TextDrawing.params_for_label(instruction)[0]
-                layer.set_qubit(instruction['qargs'][0], Bullet())
-                layer.set_qubit(instruction['qargs'][1], Bullet())
-
-            elif instruction['name'] == 'cu3':
-                # cu3
-                params = TextDrawing.params_for_label(instruction)
-                layer.set_qubit(instruction['qargs'][0], Bullet())
-                layer.set_qubit(instruction['qargs'][1],
-                                BoxOnQuWire("U3(%s)" % ','.join(params)))
-
-            elif instruction['name'] == 'crz':
-                # crz
-                label = "Rz(%s)" % TextDrawing.params_for_label(instruction)[0]
-                layer.set_qubit(instruction['qargs'][0], Bullet())
-                layer.set_qubit(instruction['qargs'][1], BoxOnQuWire(label))
-
-            elif len(instruction['qargs']) == 1 and not instruction['cargs']:
-                # unitary gate
-                layer.set_qubit(instruction['qargs'][0],
-                                BoxOnQuWire(TextDrawing.label_for_box(instruction)))
-
-            elif len(instruction['qargs']) >= 2 and not instruction['cargs']:
-                # multiple qubit gate
-                layer.set_qu_multibox(instruction['qargs'], TextDrawing.label_for_box(instruction))
 
-            else:
-                raise VisualizationError(
-                    "Text visualizer does not know how to handle this instruction", instruction)
-
-            layer.connect_with("│", connector_label)
+            for instruction in instruction_layer:
+                layer, current_connections, connection_label = \
+                    self._instruction_to_gate(instruction, layer)
 
+                layer.connections.append((connection_label, current_connections))
+                layer.connect_with("│")
             layers.append(layer.full_layer)
 
         return layers
@@ -779,6 +805,7 @@ def __init__(self, qregs, cregs):
         self.qregs = qregs
         self.cregs = cregs
         self.qubit_layer = [None] * len(qregs)
+        self.connections = []
         self.clbit_layer = [None] * len(cregs)
 
     @property
@@ -862,25 +889,28 @@ def set_qu_multibox(self, bits, label):
         """
         self._set_multibox("qu", bits, label)
 
-    def connect_with(self, wire_char, label=None):
+    def connect_with(self, wire_char):
         """
         Connects the elements in the layer using wire_char.
         Args:
             wire_char (char): For example '║' or '│'.
-            label (string): Some connectors have a label (see cu1, for example).
         """
-        affected_bits = [bit for bit in self.full_layer if bit is not None]
 
         if len([qbit for qbit in self.qubit_layer if qbit is not None]) == 1:
             # Nothing to connect
             return
 
-        affected_bits[0].connect(wire_char, ['bot'])
-        for affected_bit in affected_bits[1:-1]:
-            affected_bit.connect(wire_char, ['bot', 'top'])
-        if not isinstance(affected_bits[-1], MultiBox):
+        for label, affected_bits in self.connections:
+
+            if not affected_bits:
+                continue
+
+            affected_bits[0].connect(wire_char, ['bot'])
+            for affected_bit in affected_bits[1:-1]:
+                affected_bit.connect(wire_char, ['bot', 'top'])
+
             affected_bits[-1].connect(wire_char, ['top'], label)
 
-        if label:
-            for affected_bit in affected_bits:
-                affected_bit.right_fill = len(label) + len(affected_bit.mid)
+            if label:
+                for affected_bit in affected_bits:
+                    affected_bit.right_fill = len(label) + len(affected_bit.mid)
diff --git a/qiskit/tools/visualization/_utils.py b/qiskit/tools/visualization/_utils.py
--- a/qiskit/tools/visualization/_utils.py
+++ b/qiskit/tools/visualization/_utils.py
@@ -48,6 +48,135 @@ def _trim(image):
     return image
 
 
+def _get_layered_instructions(circuit, reversebits=False, justify=None):
+    """
+    Given a circuit, return a tuple (qregs, cregs, ops) where
+    qregs and cregs are the quantum and classical registers
+    in order (based on reversebits) and ops is a list
+    of DAG nodes which type is "operation".
+    Args:
+        circuit (QuantumCircuit): From where the information is extracted.
+        reversebits (bool): If true the order of the bits in the registers is
+            reversed.
+        justify (str) : `left`, `right` or `none`. Defaults to `left`. Says how
+            the circuit should be justified.
+    Returns:
+        Tuple(list,list,list): To be consumed by the visualizer directly.
+    """
+
+    if justify:
+        justify.lower()
+    # default to left
+    justify = justify if justify in ('right', 'none') else 'left'
+
+    dag = circuit_to_dag(circuit)
+    ops = []
+    qregs = []
+    cregs = []
+
+    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 justify == 'none':
+        for node_no in dag.node_nums_in_topological_order():
+            node = dag.multi_graph.node[node_no]
+            if node['type'] == 'op':
+                ops.append([node])
+
+    if justify == 'left':
+        for dag_layer in dag.layers():
+            layers = []
+            current_layer = []
+
+            dag_nodes = dag_layer['graph'].op_nodes(data=True)
+            dag_nodes.sort(key=lambda tup: tup[0])
+            dag_nodes = [v for k, v in dag_nodes]
+
+            for node in dag_nodes:
+                multibit_gate = len(node['qargs']) + len(node['cargs']) > 1
+
+                if multibit_gate:
+                    # need to see if it crosses over any other nodes
+                    gate_span = _get_gate_span(qregs, node)
+
+                    all_indices = []
+                    for ins in dag_nodes:
+                        if ins != node:
+                            all_indices += _get_gate_span(qregs, ins)
+
+                    if any(i in gate_span for i in all_indices):
+                        # needs to be a new layer
+                        layers.append([node])
+                    else:
+                        # can be added
+                        current_layer.append(node)
+                else:
+                    current_layer.append(node)
+
+            layers.append(current_layer)
+            ops += layers
+
+    if justify == 'right':
+        dag_layers = []
+
+        for dag_layer in dag.layers():
+            dag_layers.append(dag_layer)
+
+        # Have to work from the end of the circuit
+        dag_layers.reverse()
+
+        # Dict per layer, keys are qubits and values are the gate
+        layer_dicts = [{}]
+
+        for dag_layer in dag_layers:
+
+            dag_instructions = dag_layer['graph'].get_op_nodes(data=True)
+
+            # sort into the order they were input
+            dag_instructions.sort(key=lambda tup: tup[0])
+            for (_, instruction) in dag_instructions:
+
+                gate_span = _get_gate_span(qregs, instruction)
+
+                added = False
+                for i in range(len(layer_dicts)):
+                    # iterate from the end
+                    curr_dict = layer_dicts[-1 - i]
+
+                    if any(index in curr_dict for index in gate_span):
+                        added = True
+
+                        if i == 0:
+                            new_dict = {}
+
+                            for index in gate_span:
+                                new_dict[index] = instruction
+                            layer_dicts.append(new_dict)
+                        else:
+                            curr_dict = layer_dicts[-i]
+                            for index in gate_span:
+                                curr_dict[index] = instruction
+
+                        break
+
+                if not added:
+                    for index in gate_span:
+                        layer_dicts[0][index] = instruction
+
+        # need to convert from dict format to layers
+        layer_dicts.reverse()
+        ops = [list(layer.values()) for layer in layer_dicts]
+
+    if reversebits:
+        qregs.reverse()
+        cregs.reverse()
+
+    return qregs, cregs, ops
+
+
 def _get_instructions(circuit, reversebits=False):
     """
     Given a circuit, return a tuple (qregs, cregs, ops) where
@@ -81,3 +210,22 @@ def _get_instructions(circuit, reversebits=False):
         cregs.reverse()
 
     return qregs, cregs, ops
+
+
+def _get_gate_span(qregs, instruction):
+    """Get the list of qubits drawing this gate would cover"""
+
+    min_index = len(qregs)
+    max_index = 0
+    for qreg in instruction['qargs']:
+        index = qregs.index(qreg)
+
+        if index < min_index:
+            min_index = index
+        if index > max_index:
+            max_index = index
+
+    if instruction['cargs']:
+        return qregs[min_index:]
+
+    return qregs[min_index:max_index + 1]


Test patch:
diff --git a/test/python/tools/visualization/references/text_ref.txt b/test/python/tools/visualization/references/text_ref.txt
--- a/test/python/tools/visualization/references/text_ref.txt
+++ b/test/python/tools/visualization/references/text_ref.txt
@@ -1,13 +1,13 @@
-        ┌───┐┌───┐┌───┐ ░       ┌───┐┌───┐┌─────┐┌───┐┌─────┐┌────┐     ┌────────────┐┌────────────┐┌────────────┐┌────────────┐┌────────────┐┌───────────────────┐┌──────────────────────────┐                                                                                ┌─┐      
-q_0: |0>┤ X ├┤ Y ├┤ Z ├─░───────┤ H ├┤ S ├┤ Sdg ├┤ T ├┤ Tdg ├┤ Id ├─|0>─┤ Rx(3.1416) ├┤ Ry(3.1416) ├┤ Rz(3.1416) ├┤ U0(3.1416) ├┤ U1(3.1416) ├┤ U2(3.1416,3.1416) ├┤ U3(3.1416,3.1416,3.1416) ├─X───■────■───■───■───■────────────────────■────────────────────■─────────■───■─┤M├──────
-        └───┘└───┘└───┘ ░  ░    └───┘└───┘└─────┘└───┘└─────┘└────┘     └────────────┘└────────────┘└────────────┘└────────────┘└────────────┘└───────────────────┘└──────────────────────────┘ │ ┌─┴─┐┌─┴─┐ │ ┌─┴─┐ │3.1416 ┌────────────┴─────────────┐┌─────┴──────┐  │   │ └╥┘┌─┐   
-q_1: |0>───────────────────░────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────X─┤ X ├┤ Y ├─■─┤ H ├─■───────┤ U3(3.1416,3.1416,3.1416) ├┤ Rz(3.1416) ├──■───X──╫─┤M├───
-                           ░  ░                                                                                                                                                                   └───┘└───┘   └───┘         └──────────────────────────┘└────────────┘┌─┴─┐ │  ║ └╥┘┌─┐
-q_2: |0>──────────────────────░────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ X ├─X──╫──╫─┤M├
-                              ░                                                                                                                                                                                                                                        └───┘    ║  ║ └╥┘
- c_0: 0 ════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╩══╬══╬═
-                                                                                                                                                                                                                                                                                   ║  ║ 
- c_1: 0 ═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╩══╬═
-                                                                                                                                                                                                                                                                                      ║ 
- c_2: 0 ══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╩═
-                                                                                                                                                                                                                                                                                        
\ No newline at end of file
+        ┌───┐┌───┐┌───┐ ░ ┌───┐┌───┐┌─────┐┌───┐┌─────┐┌────┐     ┌────────────┐┌────────────┐┌────────────┐┌────────────┐┌────────────┐┌───────────────────┐┌──────────────────────────┐                                                                                ┌─┐       
+q_0: |0>┤ X ├┤ Y ├┤ Z ├─░─┤ H ├┤ S ├┤ Sdg ├┤ T ├┤ Tdg ├┤ Id ├─|0>─┤ Rx(3.1416) ├┤ Ry(3.1416) ├┤ Rz(3.1416) ├┤ U0(3.1416) ├┤ U1(3.1416) ├┤ U2(3.1416,3.1416) ├┤ U3(3.1416,3.1416,3.1416) ├─X───■────■───■───■───■────────────────────■────────────────────■─────────■───■─┤M├───────
+        └─░─┘└───┘└───┘ ░ └───┘└───┘└─────┘└───┘└─────┘└────┘     └────────────┘└────────────┘└────────────┘└────────────┘└────────────┘└───────────────────┘└──────────────────────────┘ │ ┌─┴─┐┌─┴─┐ │ ┌─┴─┐ │3.1416 ┌────────────┴─────────────┐┌─────┴──────┐  │   │ └╥┘┌─┐    
+q_1: |0>──░───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────X─┤ X ├┤ Y ├─■─┤ H ├─■───────┤ U3(3.1416,3.1416,3.1416) ├┤ Rz(3.1416) ├──■───X──╫─┤M├────
+          ░                                                                                                                                                                                 └───┘└───┘   └───┘         └──────────────────────────┘└────────────┘┌─┴─┐ │  ║ └╥┘┌─┐ 
+q_2: |0>──░──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ X ├─X──╫──╫─┤M├─
+          ░                                                                                                                                                                                                                                                      └───┘    ║  ║ └╥┘ 
+ c_0: 0 ══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╩══╬══╬══
+                                                                                                                                                                                                                                                                             ║  ║  
+ c_1: 0 ═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╩══╬══
+                                                                                                                                                                                                                                                                                ║  
+ c_2: 0 ════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╩══
+                                                                                                                                                                                                                                                                                   
\ No newline at end of file
diff --git a/test/python/tools/visualization/test_circuit_text_drawer.py b/test/python/tools/visualization/test_circuit_text_drawer.py
--- a/test/python/tools/visualization/test_circuit_text_drawer.py
+++ b/test/python/tools/visualization/test_circuit_text_drawer.py
@@ -106,19 +106,20 @@ class TestTextDrawerGatesInCircuit(QiskitTestCase):
 
     def test_text_measure_1(self):
         """ The measure operator, using 3-bit-length registers. """
-        expected = '\n'.join(['        ┌─┐      ',
-                              'q_0: |0>┤M├──────',
-                              '        └╥┘┌─┐   ',
-                              'q_1: |0>─╫─┤M├───',
-                              '         ║ └╥┘┌─┐',
-                              'q_2: |0>─╫──╫─┤M├',
-                              '         ║  ║ └╥┘',
-                              ' c_0: 0 ═╩══╬══╬═',
-                              '            ║  ║ ',
-                              ' c_1: 0 ════╩══╬═',
-                              '               ║ ',
-                              ' c_2: 0 ═══════╩═',
-                              '                 '])
+        expected = '\n'.join(['        ┌─┐       ',
+                              'q_0: |0>┤M├───────',
+                              '        └╥┘┌─┐    ',
+                              'q_1: |0>─╫─┤M├────',
+                              '         ║ └╥┘┌─┐ ',
+                              'q_2: |0>─╫──╫─┤M├─',
+                              '         ║  ║ └╥┘ ',
+                              ' c_0: 0 ═╩══╬══╬══',
+                              '            ║  ║  ',
+                              ' c_1: 0 ════╩══╬══',
+                              '               ║  ',
+                              ' c_2: 0 ═══════╩══',
+                              '                  '])
+
         qr = QuantumRegister(3, 'q')
         cr = ClassicalRegister(3, 'c')
         circuit = QuantumCircuit(qr, cr)
@@ -127,19 +128,20 @@ def test_text_measure_1(self):
 
     def test_text_measure_1_reversebits(self):
         """ The measure operator, using 3-bit-length registers, with reversebits """
-        expected = '\n'.join(['              ┌─┐',
-                              'q_2: |0>──────┤M├',
-                              '           ┌─┐└╥┘',
-                              'q_1: |0>───┤M├─╫─',
-                              '        ┌─┐└╥┘ ║ ',
-                              'q_0: |0>┤M├─╫──╫─',
-                              '        └╥┘ ║  ║ ',
-                              ' c_2: 0 ═╬══╬══╩═',
-                              '         ║  ║    ',
-                              ' c_1: 0 ═╬══╩════',
-                              '         ║       ',
-                              ' c_0: 0 ═╩═══════',
-                              '                 '])
+        expected = '\n'.join(['              ┌─┐ ',
+                              'q_2: |0>──────┤M├─',
+                              '           ┌─┐└╥┘ ',
+                              'q_1: |0>───┤M├─╫──',
+                              '        ┌─┐└╥┘ ║  ',
+                              'q_0: |0>┤M├─╫──╫──',
+                              '        └╥┘ ║  ║  ',
+                              ' c_2: 0 ═╬══╬══╩══',
+                              '         ║  ║     ',
+                              ' c_1: 0 ═╬══╩═════',
+                              '         ║        ',
+                              ' c_0: 0 ═╩════════',
+                              '                  '])
+
         qr = QuantumRegister(3, 'q')
         cr = ClassicalRegister(3, 'c')
         circuit = QuantumCircuit(qr, cr)
@@ -148,23 +150,23 @@ def test_text_measure_1_reversebits(self):
 
     def test_text_measure_2(self):
         """ The measure operator, using some registers. """
-        expected = '\n'.join(['               ',
-                              'q1_0: |0>──────',
-                              '               ',
-                              'q1_1: |0>──────',
-                              '         ┌─┐   ',
-                              'q2_0: |0>┤M├───',
-                              '         └╥┘┌─┐',
-                              'q2_1: |0>─╫─┤M├',
-                              '          ║ └╥┘',
-                              ' c1_0: 0 ═╬══╬═',
-                              '          ║  ║ ',
-                              ' c1_1: 0 ═╬══╬═',
-                              '          ║  ║ ',
-                              ' c2_0: 0 ═╩══╬═',
-                              '             ║ ',
-                              ' c2_1: 0 ════╩═',
-                              '               '])
+        expected = '\n'.join(['                ',
+                              'q1_0: |0>───────',
+                              '                ',
+                              'q1_1: |0>───────',
+                              '         ┌─┐    ',
+                              'q2_0: |0>┤M├────',
+                              '         └╥┘┌─┐ ',
+                              'q2_1: |0>─╫─┤M├─',
+                              '          ║ └╥┘ ',
+                              ' c1_0: 0 ═╬══╬══',
+                              '          ║  ║  ',
+                              ' c1_1: 0 ═╬══╬══',
+                              '          ║  ║  ',
+                              ' c2_0: 0 ═╩══╬══',
+                              '             ║  ',
+                              ' c2_1: 0 ════╩══',
+                              '                '])
 
         qr1 = QuantumRegister(2, 'q1')
         cr1 = ClassicalRegister(2, 'c1')
@@ -176,23 +178,23 @@ def test_text_measure_2(self):
 
     def test_text_measure_2_reversebits(self):
         """ The measure operator, using some registers, with reversebits """
-        expected = '\n'.join(['            ┌─┐',
-                              'q2_1: |0>───┤M├',
-                              '         ┌─┐└╥┘',
-                              'q2_0: |0>┤M├─╫─',
-                              '         └╥┘ ║ ',
-                              'q1_1: |0>─╫──╫─',
-                              '          ║  ║ ',
-                              'q1_0: |0>─╫──╫─',
-                              '          ║  ║ ',
-                              ' c2_1: 0 ═╬══╩═',
-                              '          ║    ',
-                              ' c2_0: 0 ═╩════',
-                              '               ',
-                              ' c1_1: 0 ══════',
-                              '               ',
-                              ' c1_0: 0 ══════',
-                              '               '])
+        expected = '\n'.join(['            ┌─┐ ',
+                              'q2_1: |0>───┤M├─',
+                              '         ┌─┐└╥┘ ',
+                              'q2_0: |0>┤M├─╫──',
+                              '         └╥┘ ║  ',
+                              'q1_1: |0>─╫──╫──',
+                              '          ║  ║  ',
+                              'q1_0: |0>─╫──╫──',
+                              '          ║  ║  ',
+                              ' c2_1: 0 ═╬══╩══',
+                              '          ║     ',
+                              ' c2_0: 0 ═╩═════',
+                              '                ',
+                              ' c1_1: 0 ═══════',
+                              '                ',
+                              ' c1_0: 0 ═══════',
+                              '                '])
 
         qr1 = QuantumRegister(2, 'q1')
         cr1 = ClassicalRegister(2, 'c1')
@@ -204,15 +206,15 @@ def test_text_measure_2_reversebits(self):
 
     def test_text_swap(self):
         """ Swap drawing. """
-        expected = '\n'.join(['               ',
-                              'q1_0: |0>─X────',
-                              '          │    ',
-                              'q1_1: |0>─┼──X─',
-                              '          │  │ ',
-                              'q2_0: |0>─X──┼─',
-                              '             │ ',
-                              'q2_1: |0>────X─',
-                              '               '])
+        expected = '\n'.join(['                ',
+                              'q1_0: |0>─X─────',
+                              '          │     ',
+                              'q1_1: |0>─┼──X──',
+                              '          │  │  ',
+                              'q2_0: |0>─X──┼──',
+                              '             │  ',
+                              'q2_1: |0>────X──',
+                              '                '])
 
         qr1 = QuantumRegister(2, 'q1')
         qr2 = QuantumRegister(2, 'q2')
@@ -222,15 +224,15 @@ def test_text_swap(self):
 
     def test_text_swap_reversebits(self):
         """ Swap drawing with reversebits. """
-        expected = '\n'.join(['               ',
-                              'q2_1: |0>────X─',
-                              '             │ ',
-                              'q2_0: |0>─X──┼─',
-                              '          │  │ ',
-                              'q1_1: |0>─┼──X─',
-                              '          │    ',
-                              'q1_0: |0>─X────',
-                              '               '])
+        expected = '\n'.join(['                ',
+                              'q2_1: |0>────X──',
+                              '             │  ',
+                              'q2_0: |0>─X──┼──',
+                              '          │  │  ',
+                              'q1_1: |0>─┼──X──',
+                              '          │     ',
+                              'q1_0: |0>─X─────',
+                              '                '])
 
         qr1 = QuantumRegister(2, 'q1')
         qr2 = QuantumRegister(2, 'q2')
@@ -257,13 +259,13 @@ def test_text_cswap(self):
 
     def test_text_cswap_reversebits(self):
         """ CSwap drawing with reversebits. """
-        expected = '\n'.join(["                 ",
-                              "q_2: |0>─X──X──■─",
-                              "         │  │  │ ",
-                              "q_1: |0>─X──■──X─",
-                              "         │  │  │ ",
-                              "q_0: |0>─■──X──X─",
-                              "                 "])
+        expected = '\n'.join(['                 ',
+                              'q_2: |0>─X──X──■─',
+                              '         │  │  │ ',
+                              'q_1: |0>─X──■──X─',
+                              '         │  │  │ ',
+                              'q_0: |0>─■──X──X─',
+                              '                 '])
 
         qr = QuantumRegister(3, 'q')
         circuit = QuantumCircuit(qr)
@@ -442,15 +444,16 @@ def test_text_ccx(self):
 
     def test_text_reset(self):
         """ Reset drawing. """
-        expected = '\n'.join(['                        ',
-                              'q1_0: |0>─|0>───────────',
-                              '                        ',
-                              'q1_1: |0>──────|0>──────',
-                              '                        ',
-                              'q2_0: |0>───────────────',
-                              '                        ',
-                              'q2_1: |0>───────────|0>─',
-                              '                        '])
+        expected = '\n'.join(['              ',
+                              'q1_0: |0>─|0>─',
+                              '              ',
+                              'q1_1: |0>─|0>─',
+                              '              ',
+                              'q2_0: |0>─────',
+                              '              ',
+                              'q2_1: |0>─|0>─',
+                              '              '])
+
         qr1 = QuantumRegister(2, 'q1')
         qr2 = QuantumRegister(2, 'q2')
         circuit = QuantumCircuit(qr1, qr2)
@@ -460,15 +463,16 @@ def test_text_reset(self):
 
     def test_text_single_gate(self):
         """ Single Qbit gate drawing. """
-        expected = '\n'.join(['         ┌───┐          ',
-                              'q1_0: |0>┤ H ├──────────',
-                              '         └───┘┌───┐     ',
-                              'q1_1: |0>─────┤ H ├─────',
-                              '              └───┘     ',
-                              'q2_0: |0>───────────────',
-                              '                   ┌───┐',
-                              'q2_1: |0>──────────┤ H ├',
-                              '                   └───┘'])
+        expected = '\n'.join(['         ┌───┐',
+                              'q1_0: |0>┤ H ├',
+                              '         ├───┤',
+                              'q1_1: |0>┤ H ├',
+                              '         └───┘',
+                              'q2_0: |0>─────',
+                              '         ┌───┐',
+                              'q2_1: |0>┤ H ├',
+                              '         └───┘'])
+
         qr1 = QuantumRegister(2, 'q1')
         qr2 = QuantumRegister(2, 'q2')
         circuit = QuantumCircuit(qr1, qr2)
@@ -478,15 +482,16 @@ def test_text_single_gate(self):
 
     def test_text_barrier(self):
         """ Barrier drawing. """
-        expected = '\n'.join(['          ░    ',
-                              'q1_0: |0>─░────',
-                              '          ░    ',
-                              'q1_1: |0>─░────',
-                              '          ░    ',
-                              'q2_0: |0>──────',
-                              '             ░ ',
-                              'q2_1: |0>────░─',
-                              '             ░ '])
+        expected = '\n'.join(['          ░ ',
+                              'q1_0: |0>─░─',
+                              '          ░ ',
+                              'q1_1: |0>─░─',
+                              '          ░ ',
+                              'q2_0: |0>───',
+                              '          ░ ',
+                              'q2_1: |0>─░─',
+                              '          ░ '])
+
         qr1 = QuantumRegister(2, 'q1')
         qr2 = QuantumRegister(2, 'q2')
         circuit = QuantumCircuit(qr1, qr2)
@@ -496,15 +501,16 @@ def test_text_barrier(self):
 
     def test_text_no_barriers(self):
         """ Drawing without plotbarriers. """
-        expected = '\n'.join(['         ┌───┐               ',
-                              'q1_0: |0>┤ H ├───────────────',
-                              '         └───┘┌───┐          ',
-                              'q1_1: |0>─────┤ H ├──────────',
-                              '              └───┘┌───┐     ',
-                              'q2_0: |0>──────────┤ H ├─────',
-                              '                   └───┘┌───┐',
-                              'q2_1: |0>───────────────┤ H ├',
-                              '                        └───┘'])
+        expected = '\n'.join(['         ┌───┐     ',
+                              'q1_0: |0>┤ H ├─────',
+                              '         ├───┤     ',
+                              'q1_1: |0>┤ H ├─────',
+                              '         ├───┤     ',
+                              'q2_0: |0>┤ H ├─────',
+                              '         └───┘┌───┐',
+                              'q2_1: |0>─────┤ H ├',
+                              '              └───┘'])
+
         qr1 = QuantumRegister(2, 'q1')
         qr2 = QuantumRegister(2, 'q2')
         circuit = QuantumCircuit(qr1, qr2)
@@ -673,6 +679,170 @@ def test_text_measure_html(self):
         circuit.measure(qr, cr)
         self.assertEqual(_text_circuit_drawer(circuit)._repr_html_(), expected)
 
+    def test_text_justify_left(self):
+        """ Drawing with left justify """
+        expected = '\n'.join(['         ┌───┐   ',
+                              'q1_0: |0>┤ X ├───',
+                              '         ├───┤┌─┐',
+                              'q1_1: |0>┤ H ├┤M├',
+                              '         └───┘└╥┘',
+                              ' c1_0: 0 ══════╬═',
+                              '               ║ ',
+                              ' c1_1: 0 ══════╩═',
+                              '                 '])
+
+        qr1 = QuantumRegister(2, 'q1')
+        cr1 = ClassicalRegister(2, 'c1')
+        circuit = QuantumCircuit(qr1, cr1)
+        circuit.x(qr1[0])
+        circuit.h(qr1[1])
+        circuit.measure(qr1[1], cr1[1])
+        self.assertEqual(str(_text_circuit_drawer(circuit, justify='left')), expected)
+
+    def test_text_justify_right(self):
+        """ Drawing with right justify """
+        expected = '\n'.join(['              ┌───┐',
+                              'q1_0: |0>─────┤ X ├',
+                              '         ┌───┐└┬─┬┘',
+                              'q1_1: |0>┤ H ├─┤M├─',
+                              '         └───┘ └╥┘ ',
+                              ' c1_0: 0 ═══════╬══',
+                              '                ║  ',
+                              ' c1_1: 0 ═══════╩══',
+                              '                   '])
+
+        qr1 = QuantumRegister(2, 'q1')
+        cr1 = ClassicalRegister(2, 'c1')
+        circuit = QuantumCircuit(qr1, cr1)
+        circuit.x(qr1[0])
+        circuit.h(qr1[1])
+        circuit.measure(qr1[1], cr1[1])
+        self.assertEqual(str(_text_circuit_drawer(circuit, justify='right')), expected)
+
+    def test_text_justify_none(self):
+        """ Drawing with none justify """
+        expected = '\n'.join(['         ┌───┐        ',
+                              'q1_0: |0>┤ X ├────────',
+                              '         └───┘┌───┐┌─┐',
+                              'q1_1: |0>─────┤ H ├┤M├',
+                              '              └───┘└╥┘',
+                              ' c1_0: 0 ═══════════╬═',
+                              '                    ║ ',
+                              ' c1_1: 0 ═══════════╩═',
+                              '                      '])
+
+        qr1 = QuantumRegister(2, 'q1')
+        cr1 = ClassicalRegister(2, 'c1')
+        circuit = QuantumCircuit(qr1, cr1)
+        circuit.x(qr1[0])
+        circuit.h(qr1[1])
+        circuit.measure(qr1[1], cr1[1])
+        self.assertEqual(str(_text_circuit_drawer(circuit, justify='none')), expected)
+
+    def test_text_justify_left_barrier(self):
+        """ Left justify respects barriers"""
+        expected = '\n'.join(['         ┌───┐ ░      ',
+                              'q1_0: |0>┤ H ├─░──────',
+                              '         └───┘ ░ ┌───┐',
+                              'q1_1: |0>──────░─┤ H ├',
+                              '               ░ └───┘'])
+
+        qr1 = QuantumRegister(2, 'q1')
+        circuit = QuantumCircuit(qr1)
+        circuit.h(qr1[0])
+        circuit.barrier(qr1)
+        circuit.h(qr1[1])
+        self.assertEqual(str(_text_circuit_drawer(circuit, justify='left')), expected)
+
+    def test_text_justify_right_barrier(self):
+        """ Right justify respects barriers """
+        expected = '\n'.join(['         ┌───┐ ░      ',
+                              'q1_0: |0>┤ H ├─░──────',
+                              '         └───┘ ░ ┌───┐',
+                              'q1_1: |0>──────░─┤ H ├',
+                              '               ░ └───┘'])
+
+        qr1 = QuantumRegister(2, 'q1')
+        circuit = QuantumCircuit(qr1)
+        circuit.h(qr1[0])
+        circuit.barrier(qr1)
+        circuit.h(qr1[1])
+        self.assertEqual(str(_text_circuit_drawer(circuit, justify='right')), expected)
+
+    def test_text_overlap_cx(self):
+        """ Overlapping CX gates are drawn not overlapping"""
+        expected = '\n'.join(['                    ',
+                              'q1_0: |0>──■────────',
+                              '           │        ',
+                              'q1_1: |0>──┼────■───',
+                              '           │  ┌─┴─┐ ',
+                              'q1_2: |0>──┼──┤ X ├─',
+                              '         ┌─┴─┐└───┘ ',
+                              'q1_3: |0>┤ X ├──────',
+                              '         └───┘      '])
+
+        qr1 = QuantumRegister(4, 'q1')
+        circuit = QuantumCircuit(qr1)
+        circuit.cx(qr1[0], qr1[3])
+        circuit.cx(qr1[1], qr1[2])
+        self.assertEqual(str(_text_circuit_drawer(circuit, justify='left')), expected)
+
+    def test_text_overlap_measure(self):
+        """ Measure is drawn not overlapping"""
+        expected = '\n'.join(['         ┌─┐     ',
+                              'q1_0: |0>┤M├─────',
+                              '         └╥┘┌───┐',
+                              'q1_1: |0>─╫─┤ X ├',
+                              '          ║ └───┘',
+                              ' c1_0: 0 ═╩══════',
+                              '                 ',
+                              ' c1_1: 0 ════════',
+                              '                 '])
+
+        qr1 = QuantumRegister(2, 'q1')
+        cr1 = ClassicalRegister(2, 'c1')
+        circuit = QuantumCircuit(qr1, cr1)
+        circuit.measure(qr1[0], cr1[0])
+        circuit.x(qr1[1])
+        self.assertEqual(str(_text_circuit_drawer(circuit, justify='left')), expected)
+
+    def test_text_overlap_swap(self):
+        """ Swap is drawn in 2 separate columns"""
+        expected = '\n'.join(['                ',
+                              'q1_0: |0>─X─────',
+                              '          │     ',
+                              'q1_1: |0>─┼──X──',
+                              '          │  │  ',
+                              'q2_0: |0>─X──┼──',
+                              '             │  ',
+                              'q2_1: |0>────X──',
+                              '                '])
+
+        qr1 = QuantumRegister(2, 'q1')
+        qr2 = QuantumRegister(2, 'q2')
+        circuit = QuantumCircuit(qr1, qr2)
+        circuit.swap(qr1, qr2)
+        self.assertEqual(str(_text_circuit_drawer(circuit, justify='left')), expected)
+
+    def test_text_justify_right_measure_resize(self):
+        """ Measure gate can resize if necessary"""
+        expected = '\n'.join(['         ┌───┐',
+                              'q1_0: |0>┤ X ├',
+                              '         └┬─┬┘',
+                              'q1_1: |0>─┤M├─',
+                              '          └╥┘ ',
+                              ' c1_0: 0 ══╬══',
+                              '           ║  ',
+                              ' c1_1: 0 ══╩══',
+                              '              '])
+
+        qr1 = QuantumRegister(2, 'q1')
+        cr1 = ClassicalRegister(2, 'c1')
+        circuit = QuantumCircuit(qr1, cr1)
+        circuit.x(qr1[0])
+        circuit.measure(qr1[1], cr1[1])
+        self.assertEqual(str(_text_circuit_drawer(circuit, justify='right')), expected)
+
 
 if __name__ == '__main__':
     unittest.main()
diff --git a/test/python/transpiler/test_stochastic_swap.py b/test/python/transpiler/test_stochastic_swap.py
--- a/test/python/transpiler/test_stochastic_swap.py
+++ b/test/python/transpiler/test_stochastic_swap.py
@@ -19,7 +19,6 @@
 class TestStochasticSwap(QiskitTestCase):
     """
     Tests the StochasticSwap pass.
-
     All of the tests use a fixed seed since the results
     may depend on it.
     """
@@ -113,7 +112,6 @@ def test_trivial_case(self):
          q1:---.-------|--
                        |
          q2:-----------.--
-
          Coupling map: [1]--[0]--[2]
         """
         coupling = CouplingMap([[0, 1], [0, 2]])
@@ -135,11 +133,9 @@ def test_trivial_in_same_layer(self):
          q0:--(+)--
                |
          q1:---.---
-
          q2:--(+)--
                |
          q3:---.---
-
          Coupling map: [0]--[1]--[2]--[3]
         """
         coupling = CouplingMap([[0, 1], [1, 2], [2, 3]])
@@ -163,11 +159,9 @@ def test_permute_wires_1(self):
         introduce additional swap gates. The new
         initial layout is found in pass_.initial_layout.
          q0:-------
-
          q1:--(+)--
                |
          q2:---.---
-
          Coupling map: [1]--[0]--[2]
         """
         coupling = CouplingMap([[0, 1], [0, 2]])
@@ -189,7 +183,6 @@ def test_permute_wires_2(self):
          qr1:---|--------
                 |
          qr2:--(+)-------
-
          Coupling map: [0]--[1]--[2]
         """
         coupling = CouplingMap([[1, 0], [1, 2]])
@@ -214,7 +207,6 @@ def test_permute_wires_3(self):
          qr2:---|----|--
                 |    |
          qr3:---.---(+)-
-
          Coupling map: [0]--[1]--[2]--[3]
         """
         coupling = CouplingMap([[0, 1], [1, 2], [2, 3]])
@@ -241,9 +233,7 @@ def test_permute_wires_4(self):
          qr2:-------|---
                     |
          qr3:--[H]--.---
-
          Coupling map: [0]--[1]--[2]--[3]
-
          qr0:------X---------
                    |
          qr1:------X-(+)-----
@@ -251,7 +241,6 @@ def test_permute_wires_4(self):
          qr2:------X--.------
                    |
          qr3:-[H]--X---------
-
         """
         coupling = CouplingMap([[0, 1], [1, 2], [2, 3]])
 
@@ -283,7 +272,6 @@ def test_permute_wires_5(self):
          qr2:---|-------
                 |
          qr3:---.--[H]--
-
          Coupling map: [0]--[1]--[2]--[3]
         """
         coupling = CouplingMap([[0, 1], [1, 2], [2, 3]])
@@ -308,7 +296,6 @@ def test_permute_wires_6(self):
          qr2:---|--------|--
                 |        |
          qr3:---.--[H]--(+)-
-
          Coupling map: [0]--[1]--[2]--[3]
         """
         coupling = CouplingMap([[0, 1], [1, 2], [2, 3]])
@@ -327,7 +314,6 @@ def test_permute_wires_6(self):
 
     def test_overoptimization_case(self):
         """Check mapper overoptimization.
-
         The mapper should not change the semantics of the input.
         An overoptimization introduced issue #81:
         https://github.com/Qiskit/qiskit-terra/issues/81
@@ -415,7 +401,6 @@ def test_overoptimization_case(self):
 
     def test_already_mapped(self):
         """Circuit not remapped if matches topology.
-
         See: https://github.com/Qiskit/qiskit-terra/issues/342
         """
         coupling = CouplingMap(