Repository: PennyLaneAI/pennylane
Pull request #2128 (2022-01-26 17:03:14)

New draw transform
This PR updates the `qml.draw` transform to use the new `qml.drawer.tape_text` function. The old transform can be accessed by `qml.transforms.draw_old`.

## Differences

The new function uses a different algorithm to place the operations into layers, see `qml.drawer.drawable_layers` versus `CircuitGraph.greedy_layers`. This can result in a different placement of operations.

We now assume Unicode support, given how universal Unicode support is.  Therefore the new draw does not have a `charset` keyword.

Parameters are now omitted by default.  The users can configure the display resolution of parameters via the `decimals` keyword.

Spacing is slightly different.

`wire_order` can now contain wires not on the device's wires.  Any wire acted on by operations but not present in the `wire_order` will be placed below everything in the `wire_order`.

The new drawer restricts to fix-width characters, avoiding the use of characters like ⊗ and ⟩, as those can mess up the alignment.

## Example

```python
dev = qml.device('default.qubit', wires=["a", -1, "q2"])

@qml.qnode(dev)
def circuit():
    qml.Hadamard(wires=-1)
    qml.CNOT(wires=["a", "q2"])
    qml.RX(0.2, wires="a")
    return qml.expval(qml.PauliX(wires="q2"))
```

```
>>> print(qml.draw(circuit)())
 a: ────╭C──RX─┤     
-1: ──H─│──────┤     
q2: ────╰X─────┤  <X>
>>> print(qml.transforms.draw_old(circuit)())
  a: ─────╭C──RX(0.2)──┤     
 -1: ──H──│────────────┤     
 q2: ─────╰X───────────┤ ⟨X⟩ 
```

There are failing tests due to the old qnode, which will likely be removed in the next release anyway.

github-actions[bot]: Hello. You may have forgotten to update the changelog!
Please edit [`doc/releases/changelog-dev.md`](/PennyLaneAI/pennylane/blob/master/doc/releases/changelog-dev.md) with:
* A one-to-two sentence description of the change. You may include a small working example for new features.
* A link back to this PR.
* Your name (or GitHub username) in the contributors section.
albi3ro: [sc-12940]
dime10: @albi3ro could mark or reply to the comments you've addressed?
codecov[bot]: # [Codecov](https://codecov.io/gh/PennyLaneAI/pennylane/pull/2128?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) Report
> Merging [#2128](https://codecov.io/gh/PennyLaneAI/pennylane/pull/2128?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) (b5af589) into [master](https://codecov.io/gh/PennyLaneAI/pennylane/commit/00cdc9250be0e4b3d1c7fcebed649de0de5843bd?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) (00cdc92) will **decrease** coverage by `2.78%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/PennyLaneAI/pennylane/pull/2128/graphs/tree.svg?width=650&height=150&src=pr&token=9S3YzlUgGk&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI)](https://codecov.io/gh/PennyLaneAI/pennylane/pull/2128?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI)

```diff
@@            Coverage Diff             @@
##           master    #2128      +/-   ##
==========================================
- Coverage   99.21%   96.42%   -2.79%     
==========================================
  Files         231      231              
  Lines       17901    17916      +15     
==========================================
- Hits        17760    17276     -484     
- Misses        141      640     +499     
```


| [Impacted Files](https://codecov.io/gh/PennyLaneAI/pennylane/pull/2128?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) | Coverage Δ | |
|---|---|---|
| [pennylane/drawer/tape\_text.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/2128/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL2RyYXdlci90YXBlX3RleHQucHk=) | `100.00% <100.00%> (ø)` | |
| [pennylane/transforms/\_\_init\_\_.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/2128/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL3RyYW5zZm9ybXMvX19pbml0X18ucHk=) | `100.00% <100.00%> (ø)` | |
| [pennylane/transforms/draw.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/2128/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL3RyYW5zZm9ybXMvZHJhdy5weQ==) | `100.00% <100.00%> (ø)` | |
| [pennylane/interfaces/batch/jax.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/2128/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL2ludGVyZmFjZXMvYmF0Y2gvamF4LnB5) | `0.00% <0.00%> (-100.00%)` | :arrow_down: |
| [pennylane/interfaces/batch/jax\_jit.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/2128/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL2ludGVyZmFjZXMvYmF0Y2gvamF4X2ppdC5weQ==) | `0.00% <0.00%> (-100.00%)` | :arrow_down: |
| [pennylane/interfaces/jax.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/2128/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL2ludGVyZmFjZXMvamF4LnB5) | `0.00% <0.00%> (-97.44%)` | :arrow_down: |
| [pennylane/devices/default\_qubit\_jax.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/2128/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL2RldmljZXMvZGVmYXVsdF9xdWJpdF9qYXgucHk=) | `0.00% <0.00%> (-96.63%)` | :arrow_down: |
| [pennylane/qnn/cost.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/2128/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL3Fubi9jb3N0LnB5) | `42.85% <0.00%> (-57.15%)` | :arrow_down: |
| [pennylane/transforms/classical\_jacobian.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/2128/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL3RyYW5zZm9ybXMvY2xhc3NpY2FsX2phY29iaWFuLnB5) | `77.08% <0.00%> (-22.92%)` | :arrow_down: |
| [pennylane/math/utils.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/2128/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL21hdGgvdXRpbHMucHk=) | `84.41% <0.00%> (-15.59%)` | :arrow_down: |
| ... and [16 more](https://codecov.io/gh/PennyLaneAI/pennylane/pull/2128/diff?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/PennyLaneAI/pennylane/pull/2128?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/PennyLaneAI/pennylane/pull/2128?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI). Last update [00cdc92...b5af589](https://codecov.io/gh/PennyLaneAI/pennylane/pull/2128?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI).


Patch:
diff --git a/doc/releases/changelog-dev.md b/doc/releases/changelog-dev.md
index 6a41140d1..097dfd7c1 100644
--- a/doc/releases/changelog-dev.md
+++ b/doc/releases/changelog-dev.md
@@ -4,6 +4,24 @@
 
 <h3>New features since last release</h3>
 
+* The text based drawer accessed via `qml.draw` has been overhauled. The new drawer has 
+  a `decimals` keyword for controlling parameter rounding, a different algorithm for determining positions, 
+  deprecation of the `charset` keyword, and minor cosmetic changes.
+  [(#2128)](https://github.com/PennyLaneAI/pennylane/pull/2128)
+
+  ```
+  @qml.qnode(qml.device('lightning.qubit', wires=2))
+  def circuit(a, w):
+      qml.Hadamard(0)
+      qml.CRX(a, wires=[0, 1])
+      qml.Rot(*w, wires=[1])
+      qml.CRX(-a, wires=[0, 1])
+      return qml.expval(qml.PauliZ(0) @ qml.PauliZ(1))
+  ```
+  >>> print(qml.draw(circuit, decimals=2)(a=2.3, w=[1.2, 3.2, 0.7]))
+  0: ──H─╭C─────────────────────────────╭C─────────┤ ╭<Z@Z>
+  1: ────╰RX(2.30)──Rot(1.20,3.20,0.70)─╰RX(-2.30)─┤ ╰<Z@Z>
+
 * Parametric operations now have the `parameter_frequencies`
   method that returns the frequencies with which a parameter
   enters a circuit when using the operation.
@@ -103,5 +121,6 @@
 
 This release contains contributions from (in alphabetical order):
 
-Thomas Bromley, Anthony Hayes, Josh Izaac, Maria Fernanda Morris, Antal Száva,
+Thomas Bromley, Anthony Hayes, Josh Izaac, Christina Lee, Maria Fernanda Morris, Antal Száva,
 David Wierichs
+
diff --git a/pennylane/drawer/tape_text.py b/pennylane/drawer/tape_text.py
index ee6a76f0d..735111146 100644
--- a/pennylane/drawer/tape_text.py
+++ b/pennylane/drawer/tape_text.py
@@ -252,7 +252,7 @@ def tape_text(
                 finished_lines += totals
                 finished_lines[-1] += "\n"
                 totals = [filler] * n_wires
-                line_length = 1 + max_label_len
+                line_length = 2 + max_label_len
 
             totals = [filler.join([t, s]) for t, s in zip(totals, layer_str)]
         if ender:
diff --git a/pennylane/transforms/__init__.py b/pennylane/transforms/__init__.py
index 5abfcf05a..77a52bdcd 100644
--- a/pennylane/transforms/__init__.py
+++ b/pennylane/transforms/__init__.py
@@ -138,7 +138,7 @@ from .classical_jacobian import classical_jacobian
 from .compile import compile
 from .control import ControlledOperation, ctrl
 from .decompositions import zyz_decomposition, two_qubit_decomposition
-from .draw import draw, draw_mpl
+from .draw import draw, draw_mpl, draw_old
 from .hamiltonian_expand import hamiltonian_expand
 from .measurement_grouping import measurement_grouping
 from .metric_tensor import metric_tensor
diff --git a/pennylane/transforms/draw.py b/pennylane/transforms/draw.py
index e34b514fc..72e985946 100644
--- a/pennylane/transforms/draw.py
+++ b/pennylane/transforms/draw.py
@@ -18,11 +18,11 @@ Contains the drawing function.
 """
 from functools import wraps
 
-from pennylane.drawer import tape_mpl
+from pennylane.drawer import tape_mpl, tape_text
 from pennylane.wires import Wires
 
 
-def draw(
+def draw_old(
     qnode,
     charset="unicode",
     wire_order=None,
@@ -152,6 +152,181 @@ def draw(
     return wrapper
 
 
+def draw(
+    qnode,
+    wire_order=None,
+    show_all_wires=False,
+    decimals=2,
+    max_length=100,
+    expansion_strategy=None,
+):
+    """Create a function that draws the given qnode.
+
+    Args:
+        qnode (.QNode): the input QNode that is to be drawn.
+        wire_order (Sequence[Any]): the order (from top to bottom) to print the wires of the circuit
+        show_all_wires (bool): If True, all wires, including empty wires, are printed.
+        decimals (int): How many decimal points to include when formatting operation parameters.
+            ``None`` will omit parameters from operation labels.
+        max_length (int): Maximum string width (columns) when printing the circuit
+        expansion_strategy (str): The strategy to use when circuit expansions or decompositions
+            are required.
+
+            - ``gradient``: The QNode will attempt to decompose
+              the internal circuit such that all circuit operations are supported by the gradient
+              method.
+
+            - ``device``: The QNode will attempt to decompose the internal circuit
+              such that all circuit operations are natively supported by the device.
+
+
+    Returns:
+        A function that has the same argument signature as ``qnode``. When called,
+        the function will draw the QNode.
+
+    **Example**
+
+    .. code-block:: python3
+
+        @qml.qnode(qml.device('lightning.qubit', wires=2))
+        def circuit(a, w):
+            qml.Hadamard(0)
+            qml.CRX(a, wires=[0, 1])
+            qml.Rot(*w, wires=[1])
+            qml.CRX(-a, wires=[0, 1])
+            return qml.expval(qml.PauliZ(0) @ qml.PauliZ(1))
+
+    >>> print(qml.draw(circuit)(a=2.3, w=[1.2, 3.2, 0.7]))
+    1: ────╭RX(2.30)──Rot(1.20,3.20,0.70)─╭RX(-2.30)─┤ ╭<Z@Z>
+    0: ──H─╰C─────────────────────────────╰C─────────┤ ╰<Z@Z>
+
+    .. UsageDetails::
+
+
+    By specifying the ``decimals`` keyword, parameters
+    are displayed to the specified precision. Matrix-valued parameters are never displayed.
+
+    >>> print(qml.draw(circuit, decimals=4)(a=2.3, w=[1.2, 3.2, 0.7]))
+    0: ──H─╭C─────────────────────────────────────╭C───────────┤ ╭<Z@Z>
+    1: ────╰RX(2.3000)──Rot(1.2000,3.2000,0.7000)─╰RX(-2.3000)─┤ ╰<Z@Z>
+
+    Parameters can be omitted by requesting ``decimals=None``:
+
+    >>> print(qml.draw(circuit, decimals=None)(a=2.3, w=[1.2, 3.2, 0.7]))
+    0: ──H─╭C───────╭C──┤ ╭<Z@Z>
+    1: ────╰RX──Rot─╰RX─┤ ╰<Z@Z>
+
+    If the parameters are not acted upon by classical processing like ``-a``, then
+    ``qml.draw`` can handle string-valued parameters as well:
+
+    >>> @qml.qnode(qml.device('lightning.qubit', wires=1))
+    ... def circuit2(x):
+    ...     qml.RX(x, wires=0)
+    ...     return qml.expval(qml.PauliZ(0))
+    >>> print(qml.draw(circuit2)("x"))
+    0: ──RX(x)─┤  <Z>
+
+    The ``max_length`` keyword warps long circuits:
+
+    .. code-block:: python
+
+        rng = np.random.default_rng(seed=42)
+        shape = qml.StronglyEntanglingLayers.shape(n_wires=3, n_layers=3)
+        params = rng.random(shape)
+
+        @qml.qnode(qml.device('lightning.qubit', wires=3))
+        def longer_circuit(params):
+            qml.StronglyEntanglingLayers(params, wires=range(3))
+            return [qml.expval(qml.PauliZ(i)) for i in range(3)]
+
+        print(qml.draw(longer_circuit, max_length=60)(params))
+
+    .. code-block:: none
+
+        0: ──Rot(0.77,0.44,0.86)─╭C────╭X──Rot(0.45,0.37,0.93)─╭C─╭X
+        1: ──Rot(0.70,0.09,0.98)─╰X─╭C─│───Rot(0.64,0.82,0.44)─│──╰C
+        2: ──Rot(0.76,0.79,0.13)────╰X─╰C──Rot(0.23,0.55,0.06)─╰X───
+
+        ───Rot(0.83,0.63,0.76)──────────────────────╭C────╭X─┤  <Z>
+        ──╭X────────────────────Rot(0.35,0.97,0.89)─╰X─╭C─│──┤  <Z>
+        ──╰C────────────────────Rot(0.78,0.19,0.47)────╰X─╰C─┤  <Z>
+
+    The ``wire_order`` keyword specifies the order of the wires from
+    top to bottom:
+
+    >>> print(qml.draw(circuit, wire_order=[1,0])(a=2.3, w=[1.2, 3.2, 0.7]))
+    1: ────╭RX(2.30)──Rot(1.20,3.20,0.70)─╭RX(-2.30)─┤ ╭<Z@Z>
+    0: ──H─╰C─────────────────────────────╰C─────────┤ ╰<Z@Z>
+
+    If the device or ``wire_order`` has wires not used by operations, those wires are omitted
+    unless requested with ``show_all_wires=True``
+
+    >>> empty_qfunc = lambda : qml.expval(qml.PauliZ(0))
+    >>> empty_circuit = qml.QNode(empty_qfunc, qml.device('lightning.qubit', wires=3))
+    >>> print(qml.draw(empty_circuit, show_all_wires=True)())
+    0: ───┤  <Z>
+    1: ───┤
+    2: ───┤
+
+    Drawing also works on batch transformed circuits:
+
+    .. code-block:: python
+
+        @qml.gradients.param_shift(shift=0.1)
+        @qml.qnode(qml.device('lightning.qubit', wires=1))
+        def transformed_circuit(x):
+            qml.RX(x, wires=0)
+            return qml.expval(qml.PauliZ(0))
+
+        print(qml.draw(transformed_circuit)(np.array(1.0)))
+
+    .. code-block:: none
+
+        0: ──RX(1.10)─┤  <Z>
+
+        0: ──RX(0.90)─┤  <Z>
+
+    """
+
+    @wraps(qnode)
+    def wrapper(*args, **kwargs):
+
+        original_expansion_strategy = getattr(qnode, "expansion_strategy", None)
+
+        try:
+            qnode.expansion_strategy = expansion_strategy or original_expansion_strategy
+            tapes = qnode.construct(args, kwargs)
+        finally:
+            qnode.expansion_strategy = original_expansion_strategy
+
+        _wire_order = wire_order or qnode.device.wires
+
+        if tapes is not None:
+            cache = {"tape_offset": 0}
+            res = [
+                tape_text(
+                    t,
+                    wire_order=_wire_order,
+                    show_all_wires=show_all_wires,
+                    decimals=decimals,
+                    max_length=max_length,
+                    cache=cache,
+                )
+                for t in tapes[0]
+            ]
+            return "\n\n".join(res)
+
+        return tape_text(
+            qnode.qtape,
+            wire_order=_wire_order,
+            show_all_wires=show_all_wires,
+            decimals=decimals,
+            max_length=max_length,
+        )
+
+    return wrapper
+
+
 def draw_mpl(qnode, wire_order=None, show_all_wires=False, decimals=None, **kwargs):
     """Draw a qnode with matplotlib
 


Test patch:
diff --git a/tests/interfaces/test_batch_tensorflow_qnode.py b/tests/interfaces/test_batch_tensorflow_qnode.py
index fb9b37fae..a21f6fd21 100644
--- a/tests/interfaces/test_batch_tensorflow_qnode.py
+++ b/tests/interfaces/test_batch_tensorflow_qnode.py
@@ -124,10 +124,7 @@ class TestQNode:
             return qml.state()
 
         result = qml.draw(circuit)(p1=x, p3=z)
-        expected = """\
- 0: ──RX(0.1)───RX(0.4)──╭C──╭┤ State 
- 1: ──RY(0.06)───────────╰X──╰┤ State 
-"""
+        expected = "0: ──RX(0.10)──RX(0.40)─╭C─┤  State\n" "1: ──RY(0.06)───────────╰X─┤  State"
         assert result == expected
 
     def test_jacobian(self, dev_name, diff_method, mode, mocker, tol):
diff --git a/tests/interfaces/test_batch_torch_qnode.py b/tests/interfaces/test_batch_torch_qnode.py
index f170d8290..fe18a1aa0 100644
--- a/tests/interfaces/test_batch_torch_qnode.py
+++ b/tests/interfaces/test_batch_torch_qnode.py
@@ -105,23 +105,20 @@ class TestQNode:
         y = torch.tensor([0.2, 0.3], requires_grad=True)
         z = torch.tensor(0.4, requires_grad=True)
 
-        dev = qml.device("default.qubit", wires=2)
+        dev = qml.device(dev_name, wires=2)
 
-        @qnode(dev, interface="torch")
+        @qnode(dev, interface="torch", diff_method=diff_method, mode=mode)
         def circuit(p1, p2=y, **kwargs):
             qml.RX(p1, wires=0)
             qml.RY(p2[0] * p2[1], wires=1)
             qml.RX(kwargs["p3"], wires=0)
             qml.CNOT(wires=[0, 1])
-            return qml.probs(wires=0), qml.var(qml.PauliZ(1))
+            return qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliZ(1))
 
         circuit(p1=x, p3=z)
 
         result = qml.draw(circuit)(p1=x, p3=z)
-        expected = """\
- 0: ──RX(0.1)───RX(0.4)──╭C──┤ Probs  
- 1: ──RY(0.06)───────────╰X──┤ Var[Z] 
-"""
+        expected = "0: ──RX(0.10)──RX(0.40)─╭C─┤  <Z>\n" "1: ──RY(0.06)───────────╰X─┤  <Z>"
 
         assert result == expected
 
diff --git a/tests/tape/test_qnode_old.py b/tests/tape/test_qnode_old.py
index 385684718..456754b6c 100644
--- a/tests/tape/test_qnode_old.py
+++ b/tests/tape/test_qnode_old.py
@@ -826,11 +826,10 @@ class TestTapeConstruction:
 
     def test_draw_transform(self):
         """Test circuit drawing"""
-        from pennylane import numpy as anp
 
-        x = anp.array(0.1, requires_grad=True)
-        y = anp.array([0.2, 0.3], requires_grad=True)
-        z = anp.array(0.4, requires_grad=True)
+        x = pnp.array(0.1, requires_grad=True)
+        y = pnp.array([0.2, 0.3], requires_grad=True)
+        z = pnp.array(0.4, requires_grad=True)
 
         dev = qml.device("default.qubit", wires=2)
 
@@ -843,46 +842,16 @@ class TestTapeConstruction:
             return qml.expval(qml.PauliZ(0) @ qml.PauliX(1))
 
         result = draw(circuit)(p1=x, p3=z)
-        expected = """\
- 0: ──RX(0.1)───RX(0.4)──╭C──╭┤ ⟨Z ⊗ X⟩ 
- 1: ──RY(0.06)───────────╰X──╰┤ ⟨Z ⊗ X⟩ 
-"""
-
-        assert result == expected
-
-    def test_draw_transform_ascii(self):
-        """Test circuit drawing when using ASCII characters"""
-        from pennylane import numpy as anp
-
-        x = anp.array(0.1, requires_grad=True)
-        y = anp.array([0.2, 0.3], requires_grad=True)
-        z = anp.array(0.4, requires_grad=True)
-
-        dev = qml.device("default.qubit", wires=2)
-
-        @qnode(dev, interface="autograd")
-        def circuit(p1, p2, **kwargs):
-            qml.RX(p1, wires=0)
-            qml.RY(p2[0] * p2[1], wires=1)
-            qml.RX(kwargs["p3"], wires=0)
-            qml.CNOT(wires=[0, 1])
-            return qml.expval(qml.PauliZ(0) @ qml.PauliX(1))
-
-        result = draw(circuit, charset="ascii")(p1=x, p2=y, p3=z)
-        expected = """\
- 0: --RX(0.1)---RX(0.4)--+C--+| <Z @ X> 
- 1: --RY(0.06)-----------+X--+| <Z @ X> 
-"""
+        expected = "0: ──RX(0.10)──RX(0.40)─╭C─┤ ╭<Z@X>\n" "1: ──RY(0.06)───────────╰X─┤ ╰<Z@X>"
 
         assert result == expected
 
     def test_drawing(self):
         """Test circuit drawing"""
-        from pennylane import numpy as anp
 
-        x = anp.array(0.1, requires_grad=True)
-        y = anp.array([0.2, 0.3], requires_grad=True)
-        z = anp.array(0.4, requires_grad=True)
+        x = pnp.array(0.1, requires_grad=True)
+        y = pnp.array([0.2, 0.3], requires_grad=True)
+        z = pnp.array(0.4, requires_grad=True)
 
         dev = qml.device("default.qubit", wires=2)
 
@@ -896,7 +865,8 @@ class TestTapeConstruction:
 
         circuit(p1=x, p3=z)
 
-        result = circuit.draw()
+        with pytest.warns(UserWarning, match="The QNode.draw method has been deprecated."):
+            result = circuit.draw()
         expected = """\
  0: ──RX(0.1)───RX(0.4)──╭C──╭┤ ⟨Z ⊗ X⟩ 
  1: ──RY(0.06)───────────╰X──╰┤ ⟨Z ⊗ X⟩ 
@@ -924,7 +894,8 @@ class TestTapeConstruction:
 
         circuit(p1=x, p3=z)
 
-        result = circuit.draw(charset="ascii")
+        with pytest.warns(UserWarning, match="The QNode.draw method has been deprecated."):
+            result = circuit.draw(charset="ascii")
         expected = """\
  0: --RX(0.1)---RX(0.4)--+C--+| <Z @ X> 
  1: --RY(0.06)-----------+X--+| <Z @ X> 
diff --git a/tests/test_vqe.py b/tests/test_vqe.py
index 5370eb108..19c0c94c7 100644
--- a/tests/test_vqe.py
+++ b/tests/test_vqe.py
@@ -753,7 +753,7 @@ class TestNewVQE:
             return qml.expval(H1)
 
         res = qml.draw(circuit1)()
-        expected = " 0: ──H──╭┤ ⟨Hamiltonian(1, 1, 1)⟩ \n" + " 2: ─────╰┤ ⟨Hamiltonian(1, 1, 1)⟩ \n"
+        expected = "0: ──H─┤ ╭<𝓗(1.00,1.00,1.00)>\n2: ────┤ ╰<𝓗(1.00,1.00,1.00)>"
         assert res == expected
 
     def test_multiple_expvals(self):
diff --git a/tests/transforms/test_draw.py b/tests/transforms/test_draw.py
index 5567ea7fd..3dbfd9765 100644
--- a/tests/transforms/test_draw.py
+++ b/tests/transforms/test_draw.py
@@ -1,593 +1,281 @@
-# Copyright 2018-2020 Xanadu Quantum Technologies Inc.
-
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-
-#     http://www.apache.org/licenses/LICENSE-2.0
-
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-"""
-Unit tests for the draw transform.
-"""
-import functools
-import pytest
-
-import pennylane as qml
-from pennylane import numpy as np
-
-
-def test_drawing():
-    """Test circuit drawing"""
-
-    x = np.array(0.1, requires_grad=True)
-    y = np.array([0.2, 0.3], requires_grad=True)
-    z = np.array(0.4, requires_grad=True)
-
-    dev = qml.device("default.qubit", wires=2)
-
-    @qml.qnode(dev, interface="autograd")
-    def circuit(p1, p2=y, **kwargs):
-        qml.RX(p1, wires=0)
-        qml.RY(p2[0] * p2[1], wires=1)
-        qml.RX(kwargs["p3"], wires=0)
-        qml.CNOT(wires=[0, 1])
-        return qml.expval(qml.PauliZ(0) @ qml.PauliX(1))
-
-    result = qml.draw(circuit)(p1=x, p3=z)
-    expected = """\
- 0: ──RX(0.1)───RX(0.4)──╭C──╭┤ ⟨Z ⊗ X⟩ 
- 1: ──RY(0.06)───────────╰X──╰┤ ⟨Z ⊗ X⟩ 
-"""
-
-    assert result == expected
-
-
-def test_drawing_tf():
-    """Test circuit drawing when using TensorFlow"""
-    tf = pytest.importorskip("tensorflow")
-
-    x = tf.constant(0.1)
-    y = tf.constant([0.2, 0.3])
-    z = tf.Variable(0.4)
-
-    dev = qml.device("default.qubit", wires=2)
-
-    @qml.qnode(dev, interface="tf")
-    def circuit(p1, p2=y, **kwargs):
-        qml.RX(p1, wires=0)
-        qml.RY(p2[0] * p2[1], wires=1)
-        qml.RX(kwargs["p3"], wires=0)
-        qml.CNOT(wires=[0, 1])
-        return qml.expval(qml.PauliZ(0) @ qml.PauliX(1))
-
-    result = qml.draw(circuit)(p1=x, p3=z)
-    expected = """\
- 0: ──RX(0.1)───RX(0.4)──╭C──╭┤ ⟨Z ⊗ X⟩ 
- 1: ──RY(0.06)───────────╰X──╰┤ ⟨Z ⊗ X⟩ 
-"""
-
-    assert result == expected
-
-
-def test_drawing_torch():
-    """Test circuit drawing when using Torch"""
-    torch = pytest.importorskip("torch")
-
-    x = torch.tensor(0.1, requires_grad=True)
-    y = torch.tensor([0.2, 0.3], requires_grad=True)
-    z = torch.tensor(0.4, requires_grad=True)
-
-    dev = qml.device("default.qubit", wires=2)
-
-    @qml.qnode(dev, interface="torch")
-    def circuit(p1, p2=y, **kwargs):
-        qml.RX(p1, wires=0)
-        qml.RY(p2[0] * p2[1], wires=1)
-        qml.RX(kwargs["p3"], wires=0)
-        qml.CNOT(wires=[0, 1])
-        return qml.expval(qml.PauliZ(0) @ qml.PauliX(1))
-
-    result = qml.draw(circuit)(p1=x, p3=z)
-    expected = """\
- 0: ──RX(0.1)───RX(0.4)──╭C──╭┤ ⟨Z ⊗ X⟩ 
- 1: ──RY(0.06)───────────╰X──╰┤ ⟨Z ⊗ X⟩ 
-"""
-
-    assert result == expected
-
-
-def test_drawing_jax():
-    """Test circuit drawing when using JAX"""
-    jax = pytest.importorskip("jax")
-    jnp = jax.numpy
-
-    x = jnp.array(0.1)
-    y = jnp.array([0.2, 0.3])
-    z = jnp.array(0.4)
-
-    dev = qml.device("default.qubit", wires=2)
-
-    @qml.qnode(dev, interface="jax")
-    def circuit(p1, p2=y, **kwargs):
-        qml.RX(p1, wires=0)
-        qml.RY(p2[0] * p2[1], wires=1)
-        qml.RX(kwargs["p3"], wires=0)
-        qml.CNOT(wires=[0, 1])
-        return qml.expval(qml.PauliZ(0) @ qml.PauliX(1))
-
-    result = qml.draw(circuit)(p1=x, p3=z)
-    expected = """\
- 0: ──RX(0.1)───RX(0.4)──╭C──╭┤ ⟨Z ⊗ X⟩ 
- 1: ──RY(0.06)───────────╰X──╰┤ ⟨Z ⊗ X⟩ 
-"""
-
-    assert result == expected
-
-
-def test_drawing_ascii():
-    """Test circuit drawing when using ASCII characters"""
-    from pennylane import numpy as np
-
-    x = np.array(0.1, requires_grad=True)
-    y = np.array([0.2, 0.3], requires_grad=True)
-    z = np.array(0.4, requires_grad=True)
-
-    dev = qml.device("default.qubit", wires=2)
-
-    @qml.qnode(dev, interface="autograd")
-    def circuit(p1, p2=y, **kwargs):
-        qml.RX(p1, wires=0)
-        qml.RY(p2[0] * p2[1], wires=1)
-        qml.RX(kwargs["p3"], wires=0)
-        qml.CNOT(wires=[0, 1])
-        return qml.expval(qml.PauliZ(0) @ qml.PauliX(1))
-
-    result = qml.draw(circuit, charset="ascii")(p1=x, p3=z)
-    expected = """\
- 0: --RX(0.1)---RX(0.4)--+C--+| <Z @ X> 
- 1: --RY(0.06)-----------+X--+| <Z @ X> 
-"""
-
-    assert result == expected
-
-
-def test_show_all_wires_error():
-    """Test that show_all_wires will raise an error if the provided wire
-    order does not contain all wires on the device"""
-
-    dev = qml.device("default.qubit", wires=[-1, "a", "q2", 0])
-
-    @qml.qnode(dev)
-    def circuit():
-        qml.Hadamard(wires=-1)
-        qml.CNOT(wires=[-1, "q2"])
-        return qml.expval(qml.PauliX(wires="q2"))
-
-    with pytest.raises(ValueError, match="must contain all wires"):
-        qml.draw(circuit, show_all_wires=True, wire_order=[-1, "a"])()
-
-
-def test_missing_wire():
-    """Test that wires not specifically mentioned in the wire
-    reordering are appended at the bottom of the circuit drawing"""
-
-    dev = qml.device("default.qubit", wires=["a", -1, "q2"])
-
-    @qml.qnode(dev)
-    def circuit():
-        qml.Hadamard(wires=-1)
-        qml.CNOT(wires=["a", "q2"])
-        qml.RX(0.2, wires="a")
-        return qml.expval(qml.PauliX(wires="q2"))
-
-    # test one missing wire
-    res = qml.draw(circuit, wire_order=["q2", "a"])()
-    expected = [
-        " q2: ──╭X───────────┤ ⟨X⟩ ",
-        "  a: ──╰C──RX(0.2)──┤     ",
-        " -1: ───H───────────┤     \n",
-    ]
-
-    assert res == "\n".join(expected)
-
-    # test one missing wire
-    res = qml.draw(circuit, wire_order=["q2", -1])()
-    expected = [
-        " q2: ─────╭X───────────┤ ⟨X⟩ ",
-        " -1: ──H──│────────────┤     ",
-        "  a: ─────╰C──RX(0.2)──┤     \n",
-    ]
-
-    assert res == "\n".join(expected)
-
-    # test multiple missing wires
-    res = qml.draw(circuit, wire_order=["q2"])()
-    expected = [
-        " q2: ─────╭X───────────┤ ⟨X⟩ ",
-        " -1: ──H──│────────────┤     ",
-        "  a: ─────╰C──RX(0.2)──┤     \n",
-    ]
-
-    assert res == "\n".join(expected)
-
-
-def test_invalid_wires():
-    """Test that an exception is raised if a wire in the wire
-    ordering does not exist on the device"""
-    dev = qml.device("default.qubit", wires=["a", -1, "q2"])
-
-    @qml.qnode(dev)
-    def circuit():
-        qml.Hadamard(wires=-1)
-        qml.CNOT(wires=["a", "q2"])
-        qml.RX(0.2, wires="a")
-        return qml.expval(qml.PauliX(wires="q2"))
-
-    with pytest.raises(ValueError, match="contains wires not contained on the device"):
-        qml.draw(circuit, wire_order=["q2", 5])()
-
-
-@pytest.mark.parametrize(
-    "transform",
-    [qml.gradients.param_shift(shift=0.2), functools.partial(qml.gradients.param_shift, shift=0.2)],
-)
-def test_draw_batch_transform(transform):
-    """Test that drawing a batch transform works correctly"""
-    dev = qml.device("default.qubit", wires=1)
-
-    @transform
-    @qml.qnode(dev)
-    def circuit(x):
-        qml.Hadamard(wires=0)
-        qml.RX(x, wires=0)
-        return qml.expval(qml.PauliZ(wires=0))
-
-    # the parameter-shift transform will create two circuits; one with x+0.2
-    # and one with x-0.2.
-    res = qml.draw(circuit)(np.array(0.6, requires_grad=True))
-    expected = [" 0: ──H──RX(0.8)──┤ ⟨Z⟩ ", "", " 0: ──H──RX(0.4)──┤ ⟨Z⟩ ", ""]
-    assert res == "\n".join(expected)
-
-
-def test_direct_qnode_integration():
-    """Test that a QNode renders correctly."""
-    dev = qml.device("default.qubit", wires=2)
-
-    @qml.qnode(dev)
-    def qfunc(a, w):
-        qml.Hadamard(0)
-        qml.CRX(a, wires=[0, 1])
-        qml.Rot(w[0], w[1], w[2], wires=[1])
-        qml.CRX(-a, wires=[0, 1])
-
-        return qml.expval(qml.PauliZ(0) @ qml.PauliZ(1))
-
-    a, w = 2.3, [1.2, 3.2, 0.7]
-
-    assert qml.draw(qfunc)(a, w) == (
-        " 0: ──H──╭C────────────────────────────╭C─────────╭┤ ⟨Z ⊗ Z⟩ \n"
-        + " 1: ─────╰RX(2.3)──Rot(1.2, 3.2, 0.7)──╰RX(-2.3)──╰┤ ⟨Z ⊗ Z⟩ \n"
-    )
-
-    assert qml.draw(qfunc, charset="ascii")(a, w) == (
-        " 0: --H--+C----------------------------+C---------+| <Z @ Z> \n"
-        + " 1: -----+RX(2.3)--Rot(1.2, 3.2, 0.7)--+RX(-2.3)--+| <Z @ Z> \n"
-    )
-
-
-def test_same_wire_multiple_measurements():
-    """Test that drawing a QNode with multiple measurements on certain wires works correctly."""
-    dev = qml.device("default.qubit", wires=4)
-
-    @qml.qnode(dev)
-    def qnode(x, y):
-        qml.RY(x, wires=0)
-        qml.Hadamard(0)
-        qml.RZ(y, wires=0)
-        return [
-            qml.expval(qml.PauliX(wires=[0]) @ qml.PauliX(wires=[1]) @ qml.PauliX(wires=[2])),
-            qml.expval(qml.PauliX(wires=[0]) @ qml.PauliX(wires=[3])),
-        ]
-
-    expected = (
-        " 0: ──RY(1)──H──RZ(2)──╭┤ ⟨X ⊗ X ⊗ X⟩ ╭┤ ⟨X ⊗ X⟩ \n"
-        + " 1: ───────────────────├┤ ⟨X ⊗ X ⊗ X⟩ │┤         \n"
-        + " 2: ───────────────────╰┤ ⟨X ⊗ X ⊗ X⟩ │┤         \n"
-        + " 3: ────────────────────┤             ╰┤ ⟨X ⊗ X⟩ \n"
-    )
-    assert qml.draw(qnode)(1.0, 2.0) == expected
-
-
-def test_same_wire_multiple_measurements_many_obs():
-    """Test that drawing a QNode with multiple measurements on certain
-    wires works correctly when there are more observables than the number of
-    observables for any wire.
-    """
-    dev = qml.device("default.qubit", wires=4)
-
-    @qml.qnode(dev)
-    def qnode(x, y):
-        qml.RY(x, wires=0)
-        qml.Hadamard(0)
-        qml.RZ(y, wires=0)
-        return [
-            qml.expval(qml.PauliZ(0)),
-            qml.expval(qml.PauliZ(1)),
-            qml.expval(qml.PauliZ(0) @ qml.PauliZ(1)),
-        ]
-
-    expected = (
-        " 0: ──RY(0.3)──H──RZ(0.2)──┤ ⟨Z⟩ ┤     ╭┤ ⟨Z ⊗ Z⟩ \n"
-        + " 1: ───────────────────────┤     ┤ ⟨Z⟩ ╰┤ ⟨Z ⊗ Z⟩ \n"
-    )
-    assert qml.draw(qnode)(0.3, 0.2) == expected
-
-
-def test_qubit_circuit_with_max_length_kwdarg():
-    """Test that drawing a QNode with max_length=30 results in
-    correct circuit drawing."""
-    dev = qml.device("default.qubit", wires=3)
-
-    @qml.qnode(dev)
-    def qnode():
-        for i in range(3):
-            qml.Hadamard(wires=i)
-            qml.RX(i * 0.1, wires=i)
-            qml.RY(i * 0.1, wires=i)
-            qml.RZ(i * 0.1, wires=i)
-        return qml.expval(qml.PauliZ(0))
-
-        expected = (
-            " 0: ──H──RX(0)────RY(0)────RZ\n"
-            + " 1: ──H──RX(0.1)──RY(0.1)──RZ\n"
-            + " 2: ──H──RX(0.2)──RY(0.2)──RZ\n"
-            + " \n"
-            + " (0)────┤ ⟨Z⟩ \n"
-            + " (0.1)──┤     \n"
-            + " (0.2)──┤     \n"
-        )
-        assert qml.draw(qnode, max_length=30)() == expected
-
-
-def test_qubit_circuit_with_max_length_kwdarg():
-    """Test that drawing a QNode with max_length=30 results in
-    correct circuit drawing."""
-    dev = qml.device("default.qubit", wires=3)
-
-    @qml.qnode(dev)
-    def qnode():
-        for i in range(3):
-            qml.Hadamard(wires=i)
-            qml.RX(i * 0.1, wires=i)
-            qml.RY(i * 0.1, wires=i)
-            qml.RZ(i * 0.1, wires=i)
-        return qml.expval(qml.PauliZ(0))
-
-        expected = (
-            " 0: ──H──RX(0)────RY(0)────RZ\n"
-            + " 1: ──H──RX(0.1)──RY(0.1)──RZ\n"
-            + " 2: ──H──RX(0.2)──RY(0.2)──RZ\n"
-            + " \n"
-            + " (0)────┤ ⟨Z⟩ \n"
-            + " (0.1)──┤     \n"
-            + " (0.2)──┤     \n"
-        )
-        assert qml.draw(qnode, max_length=30)() == expected
-
-
-def test_qubit_circuit_length_under_max_length_kwdarg():
-    """Test that a qubit circuit with a circuit length less than the max_length renders correctly."""
-    dev = qml.device("default.qubit", wires=3)
-
-    @qml.qnode(dev)
-    def qnode():
-        for i in range(3):
-            qml.Hadamard(wires=i)
-            qml.RX(i * 0.1, wires=i)
-            qml.RY(i * 0.1, wires=i)
-            qml.RZ(i * 0.1, wires=i)
-        return qml.expval(qml.PauliZ(0))
-
-        expected = (
-            " 0: ──H──RX(0)────RY(0)────RZ(0)────┤ ⟨Z⟩\n"
-            + " 1: ──H──RX(0.1)──RY(0.1)──RZ(0.1)──┤    \n"
-            + " 2: ──H──RX(0.2)──RY(0.2)──RZ(0.2)──┤    \n"
-        )
-        assert qml.draw(qnode, max_length=60)() == expected
-
-
-def test_matrix_parameter_template():
-    """Assert draw method handles templates with matrix valued parameters."""
-    dev = qml.device("default.qubit", wires=1)
-
-    @qml.qnode(dev)
-    def circuit():
-        qml.AmplitudeEmbedding(np.array([0, 1]), wires=0)
-        return qml.state()
-
-    expected = " 0: ──AmplitudeEmbedding(M0)──┤ State \nM0 =\n[0.+0.j 1.+0.j]\n"
-    assert qml.draw(circuit)() == expected
-
-
-class TestWireOrdering:
-    """Tests for wire ordering functionality"""
-
-    def test_default_ordering(self):
-        """Test that the default wire ordering matches the device"""
-
-        dev = qml.device("default.qubit", wires=["a", -1, "q2"])
-
-        @qml.qnode(dev)
-        def circuit():
-            qml.Hadamard(wires=-1)
-            qml.CNOT(wires=["a", "q2"])
-            qml.RX(0.2, wires="a")
-            return qml.expval(qml.PauliX(wires="q2"))
-
-        res = qml.draw(circuit)()
-        expected = [
-            "  a: ─────╭C──RX(0.2)──┤     ",
-            " -1: ──H──│────────────┤     ",
-            " q2: ─────╰X───────────┤ ⟨X⟩ \n",
-        ]
-
-        assert res == "\n".join(expected)
-
-    def test_wire_reordering(self):
-        """Test that wires are correctly reordered"""
-
-        dev = qml.device("default.qubit", wires=["a", -1, "q2"])
-
-        @qml.qnode(dev)
-        def circuit():
-            qml.Hadamard(wires=-1)
-            qml.CNOT(wires=["a", "q2"])
-            qml.RX(0.2, wires="a")
-            return qml.expval(qml.PauliX(wires="q2"))
-
-        res = qml.draw(circuit, wire_order=["q2", "a", -1])()
-        expected = [
-            " q2: ──╭X───────────┤ ⟨X⟩ ",
-            "  a: ──╰C──RX(0.2)──┤     ",
-            " -1: ───H───────────┤     \n",
-        ]
-
-        assert res == "\n".join(expected)
-
-    def test_include_empty_wires(self):
-        """Test that empty wires are correctly included"""
-
-        dev = qml.device("default.qubit", wires=[-1, "a", "q2", 0])
-
-        @qml.qnode(dev)
-        def circuit():
-            qml.Hadamard(wires=-1)
-            qml.CNOT(wires=[-1, "q2"])
-            return qml.expval(qml.PauliX(wires="q2"))
-
-        res = qml.draw(circuit, show_all_wires=True)()
-        expected = [
-            " -1: ──H──╭C──┤     ",
-            "  a: ─────│───┤     ",
-            " q2: ─────╰X──┤ ⟨X⟩ ",
-            "  0: ─────────┤     \n",
-        ]
-
-        assert res == "\n".join(expected)
-
-    def test_show_all_wires_error(self):
-        """Test that show_all_wires will raise an error if the provided wire
-        order does not contain all wires on the device"""
-
-        dev = qml.device("default.qubit", wires=[-1, "a", "q2", 0])
-
-        @qml.qnode(dev)
-        def circuit():
-            qml.Hadamard(wires=-1)
-            qml.CNOT(wires=[-1, "q2"])
-            return qml.expval(qml.PauliX(wires="q2"))
-
-        with pytest.raises(ValueError, match="must contain all wires"):
-            qml.draw(circuit, show_all_wires=True, wire_order=[-1, "a"])()
-
-    def test_missing_wire(self):
-        """Test that wires not specifically mentioned in the wire
-        reordering are appended at the bottom of the circuit drawing"""
-
-        dev = qml.device("default.qubit", wires=["a", -1, "q2"])
-
-        @qml.qnode(dev)
-        def circuit():
-            qml.Hadamard(wires=-1)
-            qml.CNOT(wires=["a", "q2"])
-            qml.RX(0.2, wires="a")
-            return qml.expval(qml.PauliX(wires="q2"))
-
-        # test one missing wire
-        res = qml.draw(circuit, wire_order=["q2", "a"])()
-        expected = [
-            " q2: ──╭X───────────┤ ⟨X⟩ ",
-            "  a: ──╰C──RX(0.2)──┤     ",
-            " -1: ───H───────────┤     \n",
-        ]
-
-        assert res == "\n".join(expected)
-
-        # test one missing wire
-        res = qml.draw(circuit, wire_order=["q2", -1])()
-        expected = [
-            " q2: ─────╭X───────────┤ ⟨X⟩ ",
-            " -1: ──H──│────────────┤     ",
-            "  a: ─────╰C──RX(0.2)──┤     \n",
-        ]
-
-        assert res == "\n".join(expected)
-
-        # test multiple missing wires
-        res = qml.draw(circuit, wire_order=["q2"])()
-        expected = [
-            " q2: ─────╭X───────────┤ ⟨X⟩ ",
-            " -1: ──H──│────────────┤     ",
-            "  a: ─────╰C──RX(0.2)──┤     \n",
-        ]
-
-        assert res == "\n".join(expected)
-
-    def test_invalid_wires(self):
-        """Test that an exception is raised if a wire in the wire
-        ordering does not exist on the device"""
-        dev = qml.device("default.qubit", wires=["a", -1, "q2"])
-
-        @qml.qnode(dev)
-        def circuit():
-            qml.Hadamard(wires=-1)
-            qml.CNOT(wires=["a", "q2"])
-            qml.RX(0.2, wires="a")
-            return qml.expval(qml.PauliX(wires="q2"))
-
-        with pytest.raises(ValueError, match="contains wires not contained on the device"):
-            res = qml.draw(circuit, wire_order=["q2", 5])()
-
-    def test_no_ops_draws(self):
-        """Test that a QNode with no operations still draws correctly"""
-        dev = qml.device("default.qubit", wires=3)
-
-        @qml.qnode(dev)
-        def qnode():
-            return qml.expval(qml.PauliX(wires=[0]) @ qml.PauliX(wires=[1]) @ qml.PauliX(wires=[2]))
-
-        res = qml.draw(qnode)()
-        expected = [
-            " 0: ──╭┤ ⟨X ⊗ X ⊗ X⟩ \n",
-            " 1: ──├┤ ⟨X ⊗ X ⊗ X⟩ \n",
-            " 2: ──╰┤ ⟨X ⊗ X ⊗ X⟩ \n",
-        ]
-
-        assert res == "".join(expected)
-
-
-class TestOpsIntegration:
-    """Integration tests for drawing specific operations and templates"""
-
-    def test_approx_time_evolution(self):
-        """Test that a QNode with the ApproxTimeEvolution template draws
-        correctly when having the expansion strategy set."""
-        H = qml.PauliX(0) + qml.PauliZ(1) + 0.5 * qml.PauliX(0) @ qml.PauliX(1)
-
-        @qml.qnode(qml.device("default.qubit", wires=2))
-        def circuit(t):
-            qml.ApproxTimeEvolution(H, t, 2)
-            return qml.probs(wires=0)
-
-        res = qml.draw(circuit, expansion_strategy="device")(0.5)
-        expected = [
-            " 0: ──H────────RZ(0.5)──H──H──╭RZ(0.25)──H──H────────RZ(0.5)──H──H──╭RZ(0.25)──H──┤ Probs \n",
-            " 1: ──RZ(0.5)──H──────────────╰RZ(0.25)──H──RZ(0.5)──H──────────────╰RZ(0.25)──H──┤       \n",
-        ]
-
-        assert res == "".join(expected)
+# Copyright 2018-2020 Xanadu Quantum Technologies Inc.
+
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+
+#     http://www.apache.org/licenses/LICENSE-2.0
+
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""
+Integration tests for the draw transform
+"""
+import pytest
+from functools import partial
+
+import pennylane as qml
+from pennylane import numpy as np
+
+from pennylane.transforms import draw
+
+
+@qml.qnode(qml.device("default.qubit", wires=(0, "a", 1.234)))
+def circuit(x, y, z):
+    qml.RX(x, wires=0)
+    qml.RY(y, wires="a")
+    qml.RZ(z, wires=1.234)
+    return qml.expval(qml.PauliZ(0))
+
+
+class TestLabelling:
+    """Test the wire labels."""
+
+    def test_any_wire_labels(self):
+        """Test wire labels with different kinds of objects."""
+
+        split_str = draw(circuit)(1.2, 2.3, 3.4).split("\n")
+        assert split_str[0][0:6] == "    0:"
+        assert split_str[1][0:6] == "    a:"
+        assert split_str[2][0:6] == "1.234:"
+
+    def test_wire_order(self):
+        """Test wire_order keyword changes order of the wires."""
+
+        split_str = draw(circuit, wire_order=[1.234, "a", 0, "b"])(1.2, 2.3, 3.4).split("\n")
+        assert split_str[0][0:6] == "1.234:"
+        assert split_str[1][0:6] == "    a:"
+        assert split_str[2][0:6] == "    0:"
+
+    def test_show_all_wires(self):
+        """Test show_all_wires=True forces empty wires to display."""
+
+        @qml.qnode(qml.device("default.qubit", wires=(0, 1)))
+        def circuit():
+            return qml.expval(qml.PauliZ(0))
+
+        split_str = draw(circuit, show_all_wires=True)().split("\n")
+        assert split_str[0][0:2] == "0:"
+        assert split_str[1][0:2] == "1:"
+
+    def test_show_all_wires_and_wire_order(self):
+        """Test show_all_wires forces empty wires to display when empty wire is in wire order."""
+
+        @qml.qnode(qml.device("default.qubit", wires=1))
+        def circuit():
+            return qml.expval(qml.PauliZ(0))
+
+        split_str = draw(circuit, wire_order=[0, "a"], show_all_wires=True)().split("\n")
+        assert split_str[0][0:2] == "0:"
+        assert split_str[1][0:2] == "a:"
+
+
+class TestDecimals:
+    """Test the decimals keyword argument."""
+
+    def test_decimals_None(self):
+        """Test that when decimals is ``None``, parameters are omitted."""
+
+        expected = "    0: ──RX─┤  <Z>\n    a: ──RY─┤     \n1.234: ──RZ─┤     "
+        assert draw(circuit, decimals=None)(1.234, 2.345, 3.456) == expected
+
+    def test_decimals(self):
+        """Test decimals keyword makes the operation parameters included to given precision"""
+
+        expected = "    0: ──RX(1.2)─┤  <Z>\n    a: ──RY(2.3)─┤     \n1.234: ──RZ(3.5)─┤     "
+        assert draw(circuit, decimals=1)(1.234, 2.345, 3.456) == expected
+
+    def test_decimals_higher_value(self):
+        """Test all decimals places display when requested value is bigger than number precision."""
+
+        out = "    0: ──RX(1.0000)─┤  <Z>\n    a: ──RY(2.0000)─┤     \n1.234: ──RZ(3.0000)─┤     "
+        assert qml.draw(circuit, decimals=4)(1, 2, 3) == out
+
+    def test_decimals_multiparameters(self):
+        """Test decimals also displays parameters when the operation has multiple parameters."""
+
+        @qml.qnode(qml.device("default.qubit", wires=(0)))
+        def circuit(x):
+            qml.Rot(*x, wires=0)
+            return qml.expval(qml.PauliZ(0))
+
+        expected = "0: ──Rot(1.2,2.3,3.5)─┤  <Z>"
+        assert draw(circuit, decimals=1)([1.234, 2.345, 3.456]) == expected
+
+    def test_decimals_0(self):
+        """Test decimals=0 rounds to integers."""
+
+        expected = "    0: ──RX(1)─┤  <Z>\n    a: ──RY(2)─┤     \n1.234: ──RZ(3)─┤     "
+        assert draw(circuit, decimals=0)(1.234, 2.3456, 3.456) == expected
+
+    def test_qml_numpy_parameters(self):
+        """Test numpy parameters display as normal numbers."""
+
+        expected = "    0: ──RX(1.00)─┤  <Z>\n    a: ──RY(2.00)─┤     \n1.234: ──RZ(3.00)─┤     "
+        assert draw(circuit)(np.array(1), np.array(2), np.array(3)) == expected
+
+    def test_torch_parameters(self):
+        """Test torch parameters display as normal numbers."""
+
+        torch = pytest.importorskip("torch")
+        expected = "    0: ──RX(1.2)─┤  <Z>\n    a: ──RY(2.3)─┤     \n1.234: ──RZ(3.5)─┤     "
+        out = draw(circuit, decimals=1)(torch.tensor(1.23), torch.tensor(2.34), torch.tensor(3.45))
+        assert out == expected
+
+    def test_tensorflow_parameters(self):
+        """Test tensorflow parameters display as normal numbers."""
+        tf = pytest.importorskip("tensorflow")
+
+        expected = "    0: ──RX(1.2)─┤  <Z>\n    a: ──RY(2.3)─┤     \n1.234: ──RZ(3.5)─┤     "
+        out = draw(circuit, decimals=1)(tf.Variable(1.234), tf.Variable(2.345), tf.Variable(3.456))
+        assert out == expected
+
+    def test_jax_parameters(self):
+        """Test jax parameters in tape display as normal numbers."""
+        jnp = pytest.importorskip("jax.numpy")
+
+        expected = "    0: ──RX(1.2)─┤  <Z>\n    a: ──RY(2.3)─┤     \n1.234: ──RZ(3.5)─┤     "
+        out = draw(circuit, decimals=1)(jnp.array(1.234), jnp.array(2.345), jnp.array(3.456))
+        assert out == expected
+
+    def test_string_decimals(self):
+        """Test displays string valued parameters."""
+
+        expected = "    0: ──RX(x)─┤  <Z>\n    a: ──RY(y)─┤     \n1.234: ──RZ(z)─┤     "
+        assert draw(circuit)("x", "y", "z") == expected
+
+
+class TestMaxLength:
+    """Test the max_length keyword."""
+
+    def test_max_length_default(self):
+        """Test max length default to 100."""
+
+        @qml.qnode(qml.device("default.qubit", wires=1))
+        def long_circuit():
+            for _ in range(100):
+                qml.PauliX(0)
+            return qml.expval(qml.PauliZ(0))
+
+        out = draw(long_circuit)()
+        assert 95 <= max(len(s) for s in out.split("\n")) <= 100
+
+    @pytest.mark.parametrize("ml", [10, 15, 20])
+    def test_setting_max_length(self, ml):
+        @qml.qnode(qml.device("default.qubit", wires=1))
+        def long_circuit():
+            for _ in range(10):
+                qml.PauliX(0)
+            return [qml.expval(qml.PauliZ(0)) for _ in range(4)]
+
+        out = draw(long_circuit, max_length=ml)()
+        assert max(len(s) for s in out.split("\n")) <= ml
+
+
+class TestLayering:
+    """Test operations are placed in the correct locations."""
+
+    def test_adjacent_ops(self):
+        """Test non-blocking gates end up on same layer."""
+
+        @qml.qnode(qml.device("default.qubit", wires=3))
+        def circuit():
+            [qml.PauliX(i) for i in range(3)]
+            return [qml.expval(qml.PauliZ(i)) for i in range(3)]
+
+        expected = "0: ──X─┤  <Z>\n1: ──X─┤  <Z>\n2: ──X─┤  <Z>"
+        assert draw(circuit)() == expected
+
+    def test_blocking_ops(self):
+        """Test single qubits gates on the same wire block each other."""
+
+        @qml.qnode(qml.device("default.qubit", wires=1))
+        def circuit():
+            [qml.PauliX(0) for i in range(3)]
+            return qml.expval(qml.PauliZ(0))
+
+        expected = "0: ──X──X──X─┤  <Z>"
+
+    def test_blocking_multiwire_gate(self):
+        """Test gate gets blocked by multi-wire gate."""
+
+        @qml.qnode(qml.device("default.qubit", wires=3))
+        def circuit():
+            qml.PauliX(0)
+            qml.IsingXX(1.234, wires=(0, 2))
+            qml.PauliX(1)
+            return qml.expval(qml.PauliZ(0))
+
+        expect = (
+            "0: ──X─╭IsingXX(1.23)────┤  <Z>\n"
+            "1: ────│───────────────X─┤     \n"
+            "2: ────╰IsingXX(1.23)────┤     "
+        )
+        assert draw(circuit)() == expect
+
+
+@pytest.mark.parametrize(
+    "transform",
+    [qml.gradients.param_shift(shift=0.2), partial(qml.gradients.param_shift, shift=0.2)],
+)
+def test_draw_batch_transform(transform):
+    """Test that drawing a batch transform works correctly."""
+
+    @transform
+    @qml.qnode(qml.device("default.qubit", wires=1))
+    def circuit(x):
+        qml.Hadamard(wires=0)
+        qml.RX(x, wires=0)
+        return qml.expval(qml.PauliZ(0))
+
+    expected = "0: ──H──RX(0.8)─┤  <Z>\n\n0: ──H──RX(0.4)─┤  <Z>"
+    assert draw(circuit, decimals=1)(np.array(0.6, requires_grad=True)) == expected
+
+
+def test_nested_tapes():
+    """Test nested tapes inside the qnode."""
+
+    @qml.qnode(qml.device("default.qubit", wires=1))
+    def circuit():
+        with qml.tape.QuantumTape() as tape1:
+            qml.PauliX(0)
+            with qml.tape.QuantumTape() as tape2:
+                qml.PauliY(0)
+        with qml.tape.QuantumTape() as tape3:
+            qml.PauliZ(0)
+            with qml.tape.QuantumTape() as tape4:
+                qml.PauliX(0)
+        return qml.expval(qml.PauliZ(0))
+
+    expected = (
+        "0: ──Tape:0──Tape:1─┤  <Z>\n\n"
+        "Tape:0\n0: ──X──Tape:2─┤  \n\n"
+        "Tape:2\n0: ──Y─┤  \n\n"
+        "Tape:1\n0: ──Z──Tape:3─┤  \n\n"
+        "Tape:3\n0: ──X─┤  "
+    )
+
+    assert draw(circuit)() == expected
+
+
+def test_expansion_strategy():
+    """Test expansion strategy keyword modifies tape expansion."""
+
+    H = qml.PauliX(0) + qml.PauliZ(1) + 0.5 * qml.PauliX(0) @ qml.PauliX(1)
+
+    @qml.qnode(qml.device("default.qubit", wires=2))
+    def circuit(t):
+        qml.ApproxTimeEvolution(H, t, 2)
+        return qml.probs(wires=0)
+
+    expected_gradient = "0: ─╭ApproxTimeEvolution─┤  Probs\n1: ─╰ApproxTimeEvolution─┤       "
+    assert draw(circuit, expansion_strategy="gradient", decimals=None)(0.5)
+
+    expected_device = (
+        "0: ──H────────MultiRZ──H──H─╭MultiRZ──H──H────────MultiRZ──H──H─╭MultiRZ──H─┤  Probs\n"
+        "1: ──MultiRZ──H─────────────╰MultiRZ──H──MultiRZ──H─────────────╰MultiRZ──H─┤       "
+    )
+    assert draw(circuit, expansion_strategy="device", decimals=None)(0.5)
diff --git a/tests/transforms/test_draw_old.py b/tests/transforms/test_draw_old.py
new file mode 100644
index 000000000..3acba1d45
--- /dev/null
+++ b/tests/transforms/test_draw_old.py
@@ -0,0 +1,544 @@
+# Copyright 2018-2022 Xanadu Quantum Technologies Inc.
+
+
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+
+#     http://www.apache.org/licenses/LICENSE-2.0
+
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""
+Unit tests for the old draw transform.
+"""
+import functools
+import pytest
+
+import pennylane as qml
+from pennylane import numpy as np
+
+from pennylane.transforms import draw_old
+
+
+def test_drawing():
+    """Test circuit drawing"""
+
+    x = np.array(0.1, requires_grad=True)
+    y = np.array([0.2, 0.3], requires_grad=True)
+    z = np.array(0.4, requires_grad=True)
+
+    dev = qml.device("default.qubit", wires=2)
+
+    @qml.qnode(dev, interface="autograd")
+    def circuit(p1, p2=y, **kwargs):
+        qml.RX(p1, wires=0)
+        qml.RY(p2[0] * p2[1], wires=1)
+        qml.RX(kwargs["p3"], wires=0)
+        qml.CNOT(wires=[0, 1])
+        return qml.expval(qml.PauliZ(0) @ qml.PauliX(1))
+
+    result = draw_old(circuit)(p1=x, p3=z)
+    expected = """\
+ 0: ──RX(0.1)───RX(0.4)──╭C──╭┤ ⟨Z ⊗ X⟩ 
+ 1: ──RY(0.06)───────────╰X──╰┤ ⟨Z ⊗ X⟩ 
+"""
+
+    assert result == expected
+
+
+def test_drawing_tf():
+    """Test circuit drawing when using TensorFlow"""
+    tf = pytest.importorskip("tensorflow")
+
+    x = tf.constant(0.1)
+    y = tf.constant([0.2, 0.3])
+    z = tf.Variable(0.4)
+
+    dev = qml.device("default.qubit", wires=2)
+
+    @qml.qnode(dev, interface="tf")
+    def circuit(p1, p2=y, **kwargs):
+        qml.RX(p1, wires=0)
+        qml.RY(p2[0] * p2[1], wires=1)
+        qml.RX(kwargs["p3"], wires=0)
+        qml.CNOT(wires=[0, 1])
+        return qml.expval(qml.PauliZ(0) @ qml.PauliX(1))
+
+    result = draw_old(circuit)(p1=x, p3=z)
+    expected = """\
+ 0: ──RX(0.1)───RX(0.4)──╭C──╭┤ ⟨Z ⊗ X⟩ 
+ 1: ──RY(0.06)───────────╰X──╰┤ ⟨Z ⊗ X⟩ 
+"""
+
+    assert result == expected
+
+
+def test_drawing_torch():
+    """Test circuit drawing when using Torch"""
+    torch = pytest.importorskip("torch")
+
+    x = torch.tensor(0.1, requires_grad=True)
+    y = torch.tensor([0.2, 0.3], requires_grad=True)
+    z = torch.tensor(0.4, requires_grad=True)
+
+    dev = qml.device("default.qubit", wires=2)
+
+    @qml.qnode(dev, interface="torch")
+    def circuit(p1, p2=y, **kwargs):
+        qml.RX(p1, wires=0)
+        qml.RY(p2[0] * p2[1], wires=1)
+        qml.RX(kwargs["p3"], wires=0)
+        qml.CNOT(wires=[0, 1])
+        return qml.expval(qml.PauliZ(0) @ qml.PauliX(1))
+
+    result = draw_old(circuit)(p1=x, p3=z)
+    expected = """\
+ 0: ──RX(0.1)───RX(0.4)──╭C──╭┤ ⟨Z ⊗ X⟩ 
+ 1: ──RY(0.06)───────────╰X──╰┤ ⟨Z ⊗ X⟩ 
+"""
+
+    assert result == expected
+
+
+def test_drawing_jax():
+    """Test circuit drawing when using JAX"""
+    jax = pytest.importorskip("jax")
+    jnp = jax.numpy
+
+    x = jnp.array(0.1)
+    y = jnp.array([0.2, 0.3])
+    z = jnp.array(0.4)
+
+    dev = qml.device("default.qubit", wires=2)
+
+    @qml.qnode(dev, interface="jax")
+    def circuit(p1, p2=y, **kwargs):
+        qml.RX(p1, wires=0)
+        qml.RY(p2[0] * p2[1], wires=1)
+        qml.RX(kwargs["p3"], wires=0)
+        qml.CNOT(wires=[0, 1])
+        return qml.expval(qml.PauliZ(0) @ qml.PauliX(1))
+
+    result = draw_old(circuit)(p1=x, p3=z)
+    expected = """\
+ 0: ──RX(0.1)───RX(0.4)──╭C──╭┤ ⟨Z ⊗ X⟩ 
+ 1: ──RY(0.06)───────────╰X──╰┤ ⟨Z ⊗ X⟩ 
+"""
+
+    assert result == expected
+
+
+def test_drawing_ascii():
+    """Test circuit drawing when using ASCII characters"""
+    from pennylane import numpy as np
+
+    x = np.array(0.1, requires_grad=True)
+    y = np.array([0.2, 0.3], requires_grad=True)
+    z = np.array(0.4, requires_grad=True)
+
+    dev = qml.device("default.qubit", wires=2)
+
+    @qml.qnode(dev, interface="autograd")
+    def circuit(p1, p2=y, **kwargs):
+        qml.RX(p1, wires=0)
+        qml.RY(p2[0] * p2[1], wires=1)
+        qml.RX(kwargs["p3"], wires=0)
+        qml.CNOT(wires=[0, 1])
+        return qml.expval(qml.PauliZ(0) @ qml.PauliX(1))
+
+    result = draw_old(circuit, charset="ascii")(p1=x, p3=z)
+    expected = """\
+ 0: --RX(0.1)---RX(0.4)--+C--+| <Z @ X> 
+ 1: --RY(0.06)-----------+X--+| <Z @ X> 
+"""
+
+    assert result == expected
+
+
+def test_show_all_wires_error():
+    """Test that show_all_wires will raise an error if the provided wire
+    order does not contain all wires on the device"""
+
+    dev = qml.device("default.qubit", wires=[-1, "a", "q2", 0])
+
+    @qml.qnode(dev)
+    def circuit():
+        qml.Hadamard(wires=-1)
+        qml.CNOT(wires=[-1, "q2"])
+        return qml.expval(qml.PauliX(wires="q2"))
+
+    with pytest.raises(ValueError, match="must contain all wires"):
+        draw_old(circuit, show_all_wires=True, wire_order=[-1, "a"])()
+
+
+def test_missing_wire():
+    """Test that wires not specifically mentioned in the wire
+    reordering are appended at the bottom of the circuit drawing"""
+
+    dev = qml.device("default.qubit", wires=["a", -1, "q2"])
+
+    @qml.qnode(dev)
+    def circuit():
+        qml.Hadamard(wires=-1)
+        qml.CNOT(wires=["a", "q2"])
+        qml.RX(0.2, wires="a")
+        return qml.expval(qml.PauliX(wires="q2"))
+
+    # test one missing wire
+    res = draw_old(circuit, wire_order=["q2", "a"])()
+    expected = [
+        " q2: ──╭X───────────┤ ⟨X⟩ ",
+        "  a: ──╰C──RX(0.2)──┤     ",
+        " -1: ───H───────────┤     \n",
+    ]
+
+    assert res == "\n".join(expected)
+
+    # test one missing wire
+    res = draw_old(circuit, wire_order=["q2", -1])()
+    expected = [
+        " q2: ─────╭X───────────┤ ⟨X⟩ ",
+        " -1: ──H──│────────────┤     ",
+        "  a: ─────╰C──RX(0.2)──┤     \n",
+    ]
+
+    assert res == "\n".join(expected)
+
+    # test multiple missing wires
+    res = draw_old(circuit, wire_order=["q2"])()
+    expected = [
+        " q2: ─────╭X───────────┤ ⟨X⟩ ",
+        " -1: ──H──│────────────┤     ",
+        "  a: ─────╰C──RX(0.2)──┤     \n",
+    ]
+
+    assert res == "\n".join(expected)
+
+
+def test_invalid_wires():
+    """Test that an exception is raised if a wire in the wire
+    ordering does not exist on the device"""
+    dev = qml.device("default.qubit", wires=["a", -1, "q2"])
+
+    @qml.qnode(dev)
+    def circuit():
+        qml.Hadamard(wires=-1)
+        qml.CNOT(wires=["a", "q2"])
+        qml.RX(0.2, wires="a")
+        return qml.expval(qml.PauliX(wires="q2"))
+
+    with pytest.raises(ValueError, match="contains wires not contained on the device"):
+        draw_old(circuit, wire_order=["q2", 5])()
+
+
+@pytest.mark.parametrize(
+    "transform",
+    [qml.gradients.param_shift(shift=0.2), functools.partial(qml.gradients.param_shift, shift=0.2)],
+)
+def test_draw_batch_transform(transform):
+    """Test that drawing a batch transform works correctly"""
+    dev = qml.device("default.qubit", wires=1)
+
+    @transform
+    @qml.qnode(dev)
+    def circuit(x):
+        qml.Hadamard(wires=0)
+        qml.RX(x, wires=0)
+        return qml.expval(qml.PauliZ(wires=0))
+
+    # the parameter-shift transform will create two circuits; one with x+0.2
+    # and one with x-0.2.
+    res = draw_old(circuit)(np.array(0.6, requires_grad=True))
+    expected = [" 0: ──H──RX(0.8)──┤ ⟨Z⟩ ", "", " 0: ──H──RX(0.4)──┤ ⟨Z⟩ ", ""]
+    assert res == "\n".join(expected)
+
+
+def test_direct_qnode_integration():
+    """Test that a QNode renders correctly."""
+    dev = qml.device("default.qubit", wires=2)
+
+    @qml.qnode(dev)
+    def qfunc(a, w):
+        qml.Hadamard(0)
+        qml.CRX(a, wires=[0, 1])
+        qml.Rot(w[0], w[1], w[2], wires=[1])
+        qml.CRX(-a, wires=[0, 1])
+
+        return qml.expval(qml.PauliZ(0) @ qml.PauliZ(1))
+
+    a, w = 2.3, [1.2, 3.2, 0.7]
+
+    assert draw_old(qfunc)(a, w) == (
+        " 0: ──H──╭C────────────────────────────╭C─────────╭┤ ⟨Z ⊗ Z⟩ \n"
+        + " 1: ─────╰RX(2.3)──Rot(1.2, 3.2, 0.7)──╰RX(-2.3)──╰┤ ⟨Z ⊗ Z⟩ \n"
+    )
+
+    assert draw_old(qfunc, charset="ascii")(a, w) == (
+        " 0: --H--+C----------------------------+C---------+| <Z @ Z> \n"
+        + " 1: -----+RX(2.3)--Rot(1.2, 3.2, 0.7)--+RX(-2.3)--+| <Z @ Z> \n"
+    )
+
+
+def test_same_wire_multiple_measurements():
+    """Test that drawing a QNode with multiple measurements on certain wires works correctly."""
+    dev = qml.device("default.qubit", wires=4)
+
+    @qml.qnode(dev)
+    def qnode(x, y):
+        qml.RY(x, wires=0)
+        qml.Hadamard(0)
+        qml.RZ(y, wires=0)
+        return [
+            qml.expval(qml.PauliX(wires=[0]) @ qml.PauliX(wires=[1]) @ qml.PauliX(wires=[2])),
+            qml.expval(qml.PauliX(wires=[0]) @ qml.PauliX(wires=[3])),
+        ]
+
+    expected = (
+        " 0: ──RY(1)──H──RZ(2)──╭┤ ⟨X ⊗ X ⊗ X⟩ ╭┤ ⟨X ⊗ X⟩ \n"
+        + " 1: ───────────────────├┤ ⟨X ⊗ X ⊗ X⟩ │┤         \n"
+        + " 2: ───────────────────╰┤ ⟨X ⊗ X ⊗ X⟩ │┤         \n"
+        + " 3: ────────────────────┤             ╰┤ ⟨X ⊗ X⟩ \n"
+    )
+    assert draw_old(qnode)(1.0, 2.0) == expected
+
+
+def test_same_wire_multiple_measurements_many_obs():
+    """Test that drawing a QNode with multiple measurements on certain
+    wires works correctly when there are more observables than the number of
+    observables for any wire.
+    """
+    dev = qml.device("default.qubit", wires=4)
+
+    @qml.qnode(dev)
+    def qnode(x, y):
+        qml.RY(x, wires=0)
+        qml.Hadamard(0)
+        qml.RZ(y, wires=0)
+        return [
+            qml.expval(qml.PauliZ(0)),
+            qml.expval(qml.PauliZ(1)),
+            qml.expval(qml.PauliZ(0) @ qml.PauliZ(1)),
+        ]
+
+    expected = (
+        " 0: ──RY(0.3)──H──RZ(0.2)──┤ ⟨Z⟩ ┤     ╭┤ ⟨Z ⊗ Z⟩ \n"
+        + " 1: ───────────────────────┤     ┤ ⟨Z⟩ ╰┤ ⟨Z ⊗ Z⟩ \n"
+    )
+    assert draw_old(qnode)(0.3, 0.2) == expected
+
+
+def test_qubit_circuit_length_under_max_length_kwdarg():
+    """Test that a qubit circuit with a circuit length less than the max_length renders correctly."""
+    dev = qml.device("default.qubit", wires=3)
+
+    @qml.qnode(dev)
+    def qnode():
+        for i in range(3):
+            qml.Hadamard(wires=i)
+            qml.RX(i * 0.1, wires=i)
+            qml.RY(i * 0.1, wires=i)
+            qml.RZ(i * 0.1, wires=i)
+        return qml.expval(qml.PauliZ(0))
+
+    expected = (
+        " 0: ──H──RX(0)────RY(0)────RZ(0)────┤ ⟨Z⟩\n"
+        + " 1: ──H──RX(0.1)──RY(0.1)──RZ(0.1)──┤    \n"
+        + " 2: ──H──RX(0.2)──RY(0.2)──RZ(0.2)──┤    \n"
+    )
+    assert draw_old(qnode, max_length=60)() == expected
+
+
+def test_matrix_parameter_template():
+    """Assert draw method handles templates with matrix valued parameters."""
+    dev = qml.device("default.qubit", wires=1)
+
+    @qml.qnode(dev)
+    def circuit():
+        qml.AmplitudeEmbedding(np.array([0, 1]), wires=0)
+        return qml.state()
+
+    expected = " 0: ──AmplitudeEmbedding(M0)──┤ State \nM0 =\n[0.+0.j 1.+0.j]\n"
+    assert draw_old(circuit)() == expected
+
+
+class TestWireOrdering:
+    """Tests for wire ordering functionality"""
+
+    def test_default_ordering(self):
+        """Test that the default wire ordering matches the device"""
+
+        dev = qml.device("default.qubit", wires=["a", -1, "q2"])
+
+        @qml.qnode(dev)
+        def circuit():
+            qml.Hadamard(wires=-1)
+            qml.CNOT(wires=["a", "q2"])
+            qml.RX(0.2, wires="a")
+            return qml.expval(qml.PauliX(wires="q2"))
+
+        res = draw_old(circuit)()
+        expected = [
+            "  a: ─────╭C──RX(0.2)──┤     ",
+            " -1: ──H──│────────────┤     ",
+            " q2: ─────╰X───────────┤ ⟨X⟩ \n",
+        ]
+
+        assert res == "\n".join(expected)
+
+    def test_wire_reordering(self):
+        """Test that wires are correctly reordered"""
+
+        dev = qml.device("default.qubit", wires=["a", -1, "q2"])
+
+        @qml.qnode(dev)
+        def circuit():
+            qml.Hadamard(wires=-1)
+            qml.CNOT(wires=["a", "q2"])
+            qml.RX(0.2, wires="a")
+            return qml.expval(qml.PauliX(wires="q2"))
+
+        res = draw_old(circuit, wire_order=["q2", "a", -1])()
+        expected = [
+            " q2: ──╭X───────────┤ ⟨X⟩ ",
+            "  a: ──╰C──RX(0.2)──┤     ",
+            " -1: ───H───────────┤     \n",
+        ]
+
+        assert res == "\n".join(expected)
+
+    def test_include_empty_wires(self):
+        """Test that empty wires are correctly included"""
+
+        dev = qml.device("default.qubit", wires=[-1, "a", "q2", 0])
+
+        @qml.qnode(dev)
+        def circuit():
+            qml.Hadamard(wires=-1)
+            qml.CNOT(wires=[-1, "q2"])
+            return qml.expval(qml.PauliX(wires="q2"))
+
+        res = draw_old(circuit, show_all_wires=True)()
+        expected = [
+            " -1: ──H──╭C──┤     ",
+            "  a: ─────│───┤     ",
+            " q2: ─────╰X──┤ ⟨X⟩ ",
+            "  0: ─────────┤     \n",
+        ]
+
+        assert res == "\n".join(expected)
+
+    def test_show_all_wires_error(self):
+        """Test that show_all_wires will raise an error if the provided wire
+        order does not contain all wires on the device"""
+
+        dev = qml.device("default.qubit", wires=[-1, "a", "q2", 0])
+
+        @qml.qnode(dev)
+        def circuit():
+            qml.Hadamard(wires=-1)
+            qml.CNOT(wires=[-1, "q2"])
+            return qml.expval(qml.PauliX(wires="q2"))
+
+        with pytest.raises(ValueError, match="must contain all wires"):
+            draw_old(circuit, show_all_wires=True, wire_order=[-1, "a"])()
+
+    def test_missing_wire(self):
+        """Test that wires not specifically mentioned in the wire
+        reordering are appended at the bottom of the circuit drawing"""
+
+        dev = qml.device("default.qubit", wires=["a", -1, "q2"])
+
+        @qml.qnode(dev)
+        def circuit():
+            qml.Hadamard(wires=-1)
+            qml.CNOT(wires=["a", "q2"])
+            qml.RX(0.2, wires="a")
+            return qml.expval(qml.PauliX(wires="q2"))
+
+        # test one missing wire
+        res = draw_old(circuit, wire_order=["q2", "a"])()
+        expected = [
+            " q2: ──╭X───────────┤ ⟨X⟩ ",
+            "  a: ──╰C──RX(0.2)──┤     ",
+            " -1: ───H───────────┤     \n",
+        ]
+
+        assert res == "\n".join(expected)
+
+        # test one missing wire
+        res = draw_old(circuit, wire_order=["q2", -1])()
+        expected = [
+            " q2: ─────╭X───────────┤ ⟨X⟩ ",
+            " -1: ──H──│────────────┤     ",
+            "  a: ─────╰C──RX(0.2)──┤     \n",
+        ]
+
+        assert res == "\n".join(expected)
+
+        # test multiple missing wires
+        res = draw_old(circuit, wire_order=["q2"])()
+        expected = [
+            " q2: ─────╭X───────────┤ ⟨X⟩ ",
+            " -1: ──H──│────────────┤     ",
+            "  a: ─────╰C──RX(0.2)──┤     \n",
+        ]
+
+        assert res == "\n".join(expected)
+
+    def test_invalid_wires(self):
+        """Test that an exception is raised if a wire in the wire
+        ordering does not exist on the device"""
+        dev = qml.device("default.qubit", wires=["a", -1, "q2"])
+
+        @qml.qnode(dev)
+        def circuit():
+            qml.Hadamard(wires=-1)
+            qml.CNOT(wires=["a", "q2"])
+            qml.RX(0.2, wires="a")
+            return qml.expval(qml.PauliX(wires="q2"))
+
+        with pytest.raises(ValueError, match="contains wires not contained on the device"):
+            res = draw_old(circuit, wire_order=["q2", 5])()
+
+    def test_no_ops_draws(self):
+        """Test that a QNode with no operations still draws correctly"""
+        dev = qml.device("default.qubit", wires=3)
+
+        @qml.qnode(dev)
+        def qnode():
+            return qml.expval(qml.PauliX(wires=[0]) @ qml.PauliX(wires=[1]) @ qml.PauliX(wires=[2]))
+
+        res = draw_old(qnode)()
+        expected = [
+            " 0: ──╭┤ ⟨X ⊗ X ⊗ X⟩ \n",
+            " 1: ──├┤ ⟨X ⊗ X ⊗ X⟩ \n",
+            " 2: ──╰┤ ⟨X ⊗ X ⊗ X⟩ \n",
+        ]
+
+        assert res == "".join(expected)
+
+
+class TestOpsIntegration:
+    """Integration tests for drawing specific operations and templates"""
+
+    def test_approx_time_evolution(self):
+        """Test that a QNode with the ApproxTimeEvolution template draws
+        correctly when having the expansion strategy set."""
+        H = qml.PauliX(0) + qml.PauliZ(1) + 0.5 * qml.PauliX(0) @ qml.PauliX(1)
+
+        @qml.qnode(qml.device("default.qubit", wires=2))
+        def circuit(t):
+            qml.ApproxTimeEvolution(H, t, 2)
+            return qml.probs(wires=0)
+
+        res = draw_old(circuit, expansion_strategy="device")(0.5)
+        expected = [
+            " 0: ──H────────RZ(0.5)──H──H──╭RZ(0.25)──H──H────────RZ(0.5)──H──H──╭RZ(0.25)──H──┤ Probs \n",
+            " 1: ──RZ(0.5)──H──────────────╰RZ(0.25)──H──RZ(0.5)──H──────────────╰RZ(0.25)──H──┤       \n",
+        ]
+
+        assert res == "".join(expected)