From be322f63bcbc4f2ded720751b21c59bfb046b608 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Mon, 4 May 2020 18:15:07 -0400 Subject: [PATCH 1/6] Handle instructions without label in mpl drawer Currently the mpl drawer is unconditionally accessing a label attribute for several classes of instructions. However, it is not guaranteed that a label is set for these instructions. This can cause a failure when going to draw a circuit with these instructions if the label doesn't exist. This commit fixes the issue by using a getattr and fixing the fallback behavior to one that actually works. --- qiskit/visualization/matplotlib.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/qiskit/visualization/matplotlib.py b/qiskit/visualization/matplotlib.py index 8d0460415bd1..fa016c94af0e 100644 --- a/qiskit/visualization/matplotlib.py +++ b/qiskit/visualization/matplotlib.py @@ -863,13 +863,13 @@ def _draw_ops(self, verbose=False): elif op.name == 'initialize': vec = '[%s]' % param self._custom_multiqubit_gate(q_xy, wide=_iswide, - text=op.op.label or "|psi>", + text=getattr(op.op, 'label', "|psi>"), subtext=vec) elif op.name == 'unitary': # TODO(mtreinish): Look into adding the unitary to the # subtext self._custom_multiqubit_gate(q_xy, wide=_iswide, - text=op.op.label or "Unitary") + text=getattr(op.op, 'label', "Unitary")) elif isinstance(op.op, ControlledGate) and op.name not in [ 'ccx', 'cx', 'c3x', 'c4x', 'cy', 'cz', 'ch', 'cu1', 'cu3', 'crz', 'cswap']: @@ -1007,12 +1007,12 @@ def _draw_ops(self, verbose=False): elif op.name in ['dcx', 'iswap']: self._custom_multiqubit_gate(q_xy, c_xy, wide=_iswide, fc=self._style.dispcol[op.name], - text=op.op.label or op.name) + text=getattr(op.op, 'label', op.name)) # Custom gate else: self._custom_multiqubit_gate(q_xy, c_xy, wide=_iswide, - text=op.op.label or op.name) + text=getattr(op.op, 'label', op.name)) # # draw multi-qubit gates (n=3) # @@ -1049,7 +1049,7 @@ def _draw_ops(self, verbose=False): # draw custom multi-qubit gate elif len(q_xy) > 5: self._custom_multiqubit_gate(q_xy, c_xy, wide=_iswide, - text=op.op.label or op.name) + text=getattr(op.opm 'label', op.name)) else: logger.critical('Invalid gate %s', op) raise exceptions.VisualizationError('invalid gate {}'.format(op)) From d21d4b41d82ed442abbc4356d734e3031fc6746d Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Tue, 5 May 2020 07:23:32 -0400 Subject: [PATCH 2/6] Fix typo --- qiskit/visualization/matplotlib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/visualization/matplotlib.py b/qiskit/visualization/matplotlib.py index fa016c94af0e..f7dbc22c7932 100644 --- a/qiskit/visualization/matplotlib.py +++ b/qiskit/visualization/matplotlib.py @@ -1049,7 +1049,7 @@ def _draw_ops(self, verbose=False): # draw custom multi-qubit gate elif len(q_xy) > 5: self._custom_multiqubit_gate(q_xy, c_xy, wide=_iswide, - text=getattr(op.opm 'label', op.name)) + text=getattr(op.op, 'label', op.name)) else: logger.critical('Invalid gate %s', op) raise exceptions.VisualizationError('invalid gate {}'.format(op)) From 63d6b5938290d3d1d817460b8a1c67229b878ec5 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Tue, 5 May 2020 07:42:58 -0400 Subject: [PATCH 3/6] Fix fallback logic --- qiskit/visualization/matplotlib.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/qiskit/visualization/matplotlib.py b/qiskit/visualization/matplotlib.py index f7dbc22c7932..ee098bdd55fd 100644 --- a/qiskit/visualization/matplotlib.py +++ b/qiskit/visualization/matplotlib.py @@ -863,13 +863,13 @@ def _draw_ops(self, verbose=False): elif op.name == 'initialize': vec = '[%s]' % param self._custom_multiqubit_gate(q_xy, wide=_iswide, - text=getattr(op.op, 'label', "|psi>"), + text=getattr(op.op, 'label') or "|psi>", subtext=vec) elif op.name == 'unitary': # TODO(mtreinish): Look into adding the unitary to the # subtext self._custom_multiqubit_gate(q_xy, wide=_iswide, - text=getattr(op.op, 'label', "Unitary")) + text=getattr(op.op, 'label') or "Unitary") elif isinstance(op.op, ControlledGate) and op.name not in [ 'ccx', 'cx', 'c3x', 'c4x', 'cy', 'cz', 'ch', 'cu1', 'cu3', 'crz', 'cswap']: @@ -1007,12 +1007,12 @@ def _draw_ops(self, verbose=False): elif op.name in ['dcx', 'iswap']: self._custom_multiqubit_gate(q_xy, c_xy, wide=_iswide, fc=self._style.dispcol[op.name], - text=getattr(op.op, 'label', op.name)) + text=getattr(op.op, 'label') or op.op.name) # Custom gate else: self._custom_multiqubit_gate(q_xy, c_xy, wide=_iswide, - text=getattr(op.op, 'label', op.name)) + text=getattr(op.op, 'label') or op.op.name) # # draw multi-qubit gates (n=3) # @@ -1044,12 +1044,12 @@ def _draw_ops(self, verbose=False): # custom gate else: self._custom_multiqubit_gate(q_xy, c_xy, wide=_iswide, - text=getattr(op.op, 'label', None) or op.name) + text=getattr(op.op, 'label', None) or op.op.name) # draw custom multi-qubit gate elif len(q_xy) > 5: self._custom_multiqubit_gate(q_xy, c_xy, wide=_iswide, - text=getattr(op.op, 'label', op.name)) + text=getattr(op.op, 'label') or op.op.name) else: logger.critical('Invalid gate %s', op) raise exceptions.VisualizationError('invalid gate {}'.format(op)) From 8eaf8646ff5fd19ae6c461fc19f5f9cb8da8676b Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Tue, 5 May 2020 08:29:33 -0400 Subject: [PATCH 4/6] Fix lint --- qiskit/visualization/matplotlib.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qiskit/visualization/matplotlib.py b/qiskit/visualization/matplotlib.py index ee098bdd55fd..8a0c1ccf98c1 100644 --- a/qiskit/visualization/matplotlib.py +++ b/qiskit/visualization/matplotlib.py @@ -1044,7 +1044,8 @@ def _draw_ops(self, verbose=False): # custom gate else: self._custom_multiqubit_gate(q_xy, c_xy, wide=_iswide, - text=getattr(op.op, 'label', None) or op.op.name) + text=getattr(op.op, + 'label') or op.op.name) # draw custom multi-qubit gate elif len(q_xy) > 5: From 25b957cf5249da2d0440ea5ab67b133153bb4865 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Tue, 30 Jun 2020 14:15:27 -0400 Subject: [PATCH 5/6] Fix logic to handle both no label and None label --- qiskit/visualization/matplotlib.py | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/qiskit/visualization/matplotlib.py b/qiskit/visualization/matplotlib.py index 8a0c1ccf98c1..8ec252c6c0ec 100644 --- a/qiskit/visualization/matplotlib.py +++ b/qiskit/visualization/matplotlib.py @@ -862,14 +862,20 @@ def _draw_ops(self, verbose=False): self._barrier(_barriers) elif op.name == 'initialize': vec = '[%s]' % param + text_str = getattr(op.op, 'label', None) + if not text_str: + text_str = "|psi>" self._custom_multiqubit_gate(q_xy, wide=_iswide, - text=getattr(op.op, 'label') or "|psi>", + text=text_str, subtext=vec) elif op.name == 'unitary': # TODO(mtreinish): Look into adding the unitary to the # subtext + text_str = getattr(op.op, 'label', None) + if not text_str: + text_str = "Unitary" self._custom_multiqubit_gate(q_xy, wide=_iswide, - text=getattr(op.op, 'label') or "Unitary") + text=text_str) elif isinstance(op.op, ControlledGate) and op.name not in [ 'ccx', 'cx', 'c3x', 'c4x', 'cy', 'cz', 'ch', 'cu1', 'cu3', 'crz', 'cswap']: @@ -1005,12 +1011,16 @@ def _draw_ops(self, verbose=False): # dcx and iswap gate elif op.name in ['dcx', 'iswap']: + text_str = getattr(op.op, 'label', None) + if not text_str: + text_str = op.op.name self._custom_multiqubit_gate(q_xy, c_xy, wide=_iswide, fc=self._style.dispcol[op.name], - text=getattr(op.op, 'label') or op.op.name) + text=text_str) # Custom gate else: + text_str = getattr(op.op, 'label', None) self._custom_multiqubit_gate(q_xy, c_xy, wide=_iswide, text=getattr(op.op, 'label') or op.op.name) # @@ -1043,14 +1053,19 @@ def _draw_ops(self, verbose=False): self._line(qreg_b, qreg_t, lc=self._style.dispcol['multi']) # custom gate else: + text_str = getattr(op.op, 'label', None) + if not text_str: + text_str = op.op.name self._custom_multiqubit_gate(q_xy, c_xy, wide=_iswide, - text=getattr(op.op, - 'label') or op.op.name) + text=text_str) # draw custom multi-qubit gate elif len(q_xy) > 5: + text_str = getattr(op.op, 'label', None) + if not text_str: + text_str = op.op.name self._custom_multiqubit_gate(q_xy, c_xy, wide=_iswide, - text=getattr(op.op, 'label') or op.op.name) + text=text_str) else: logger.critical('Invalid gate %s', op) raise exceptions.VisualizationError('invalid gate {}'.format(op)) From 7323f505ad99b52a135547163adcc48f0f4806f5 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Tue, 30 Jun 2020 14:20:10 -0400 Subject: [PATCH 6/6] Fix copy and paste error --- qiskit/visualization/matplotlib.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/qiskit/visualization/matplotlib.py b/qiskit/visualization/matplotlib.py index 8ec252c6c0ec..7443aa3e2108 100644 --- a/qiskit/visualization/matplotlib.py +++ b/qiskit/visualization/matplotlib.py @@ -1021,8 +1021,10 @@ def _draw_ops(self, verbose=False): # Custom gate else: text_str = getattr(op.op, 'label', None) + if not text_str: + text_str = op.op.name self._custom_multiqubit_gate(q_xy, c_xy, wide=_iswide, - text=getattr(op.op, 'label') or op.op.name) + text=text_str) # # draw multi-qubit gates (n=3) #