In Code 1 you are trying to draw QuantumCircuit, not ket.
Error goes directly from code which tries to print quantum circuit in output type 'mpl' (line 231):
elif output == "mpl":
image = _matplotlib_circuit_drawer(
Normally in draw method
you should provide output type (text, latex, mpl ...):
qc.draw('mpl')
But when it is not provided then default value should be taken:
def circuit_drawer(
...
default_output = "text" # <- here is default output set
if config: # <- there should be some cnfig somewere?
default_output = config.get("circuit_drawer", "text")
if default_output == "auto":
if _optionals.HAS_MATPLOTLIB:
default_output = "mpl" # <- with config somewhere and default_output == "auto" and _optionals.HAS_MATPLOTLIB default_output is redefined to 'mpl'
else:
default_output = "text"
if output is None:
output = default_output
...
elif output == "mpl":
image = _matplotlib_circuit_drawer(
And the default value should be text
.
But what I see from the code is that if there is some config? and default_output is auto? and project uses matplotlib? then default_output is set to 'mpl'?
I am not familiar with Python, neither Qiskit but for debugging I suggest to provide output type explicitly and verify what will happen:
qc.draw('mpl') # 'text', 'latex', 'latex_source' etc.
So this is how we looked at source code raising error without any knowledge about Python and Qiskit.
But before trying to deep dive in such complex code let's check something simple, first try to define
qc.x(0,1)
as
qc.x(0,'1')
because source code says that the second argument is string and not integer:
def x(self, qubit: QubitSpecifier, label: Optional[str] = None) -> InstructionSet:
r"""Apply :class:`~qiskit.circuit.library.XGate`.
For the full matrix form of this gate, see the underlying gate documentation.
Args:
qubit: The qubit(s) to apply the gate to.
label: The string label of the gate in the circuit.
and maybe that is the reason for error that gate can't be visualized as suggested in that line:
File /opt/conda/lib/python3.8/site-packages/qiskit/visualization/matplotlib.py:433 in _get_layer_widths
and len(gate_text) < 3
Where this string label is used?
We can see from the code below:
def x(self, qubit: QubitSpecifier, label: Optional[str] = None) -> InstructionSet:
r"""Apply :class:`~qiskit.circuit.library.XGate`.
For the full matrix form of this gate, see the underlying gate documentation.
Args:
qubit: The qubit(s) to apply the gate to.
label: The string label of the gate in the circuit.
Returns:
A handle to the instructions created.
"""
from .library.standard_gates.x import XGate
return self.append(XGate(label=label), [qubit], [])
XGate is defined here:
\qiskit-terra\qiskit\circuit\library\standard_gates\x.py:
def __init__(self, label: Optional[str] = None):
"""Create new X gate."""
super().__init__("x", 1, [], label=label)
...
def control(
self,
num_ctrl_qubits: int = 1,
label: Optional[str] = None,
ctrl_state: Optional[Union[str, int]] = None,
):
"""Return a (multi-)controlled-X gate.
One control returns a CX gate. Two controls returns a CCX gate.
Args:
num_ctrl_qubits (int): number of control qubits.
label (str or None): An optional label for the gate [Default: None]
So analysing the code above or any next code we will find its usage at some point.
I see inheritance from Gate class where we have label:
class Gate(Instruction):
"""Unitary gate."""
def __init__(
self, name: str, num_qubits: int, params: List, label: Optional[str] = None
) -> None:
"""Create a new gate.
Args:
name: The Qobj name of the gate.
num_qubits: The number of qubits the gate acts on.
params: A list of parameters.
label: An optional label for the gate.
and then in Instruction class label is present too:
class Instruction:
"""Generic quantum instruction."""
...
label (str or None): An optional label for identifying the instruction.
Raises:
CircuitError: when the register is not in the correct format.
TypeError: when the optional label is provided, but it is not a string.
Do you see that?
TypeError: when the optional label is provided, but it is not a string.
We have got to the error in source code :)
Then we have a code that smells ... badly? :)
# Custom instruction label
# NOTE: The conditional statement checking if the `_label` attribute is
# already set is a temporary work around that can be removed after
# the next stable qiskit-aer release
if not hasattr(self, "_label"):
if label is not None and not isinstance(label, str):
raise TypeError("label expects a string or None")
self._label = label
Well, at that point we need to investigate what is going on because the purpose of that label should be rather obvious when exposed on such a high level of X gate, unless it propagates through all classes just to be used for some specific reason in classes below...
But then it should be commented better on the highest level...
Let's check documentation:
https://qiskit.org/documentation/stubs/qiskit.circuit.library.XGate.html
label¶
Return instruction label
Return type
str
Ok, so it looks like purpose of label is to use in Instruction class.
This is very generic class:
class Instruction:
"""Generic quantum instruction."""
# Class attribute to treat like barrier for transpiler, unroller, drawer
# NOTE: Using this attribute may change in the future (See issue # 5811)
...
def __init__(self, name, num_qubits, num_clbits, params, duration=None, unit="dt", label=None):
"""Create a new instruction.
...
label (str or None): An optional label for identifying the instruction.
Raises:
CircuitError: when the register is not in the correct format.
TypeError: when the optional label is provided, but it is not a string.
Still I do not know how it is uased but after using Google I have found that interesting ticket:
https://github.com/Qiskit/qiskit-terra/issues/3766
Is that an answer? :)
MPL drawer should prioritize instruction label over name #3766
When an instruction has a label, the label should be used. If a no-boxing instruction has a label, a box should be used.
I have found yet another interesting link which may suggest that the code we have was created for specific reason:
How to plot custom gate labels in Qiskit?
And the last link where custom gate is using 'label' and for sure inherits from Gate and Instruction classes:
Custom labelling of randomly generated unitaries in Qiskit
Bingo! :)