Skip to content

Commit

Permalink
new parameters in plot_bloch_multivector: figsize, font_size, a…
Browse files Browse the repository at this point in the history
…nd `title_font_size` (#7264)

* Update state_visualization.py

Closes #7263

* Introduced font size, title font size and title padding to plot_bloch_multivector

* Update state_visualization.py

Documented new kwargs.

* Fixed code formatting issues in previous commits of #7264.

* Update qiskit/visualization/bloch.py

Co-authored-by: Luciano Bello <bel@zurich.ibm.com>

* Update qiskit/visualization/bloch.py

Co-authored-by: Luciano Bello <bel@zurich.ibm.com>

* Update qiskit/visualization/state_visualization.py

Co-authored-by: Luciano Bello <bel@zurich.ibm.com>

* Update qiskit/visualization/state_visualization.py

Co-authored-by: Luciano Bello <bel@zurich.ibm.com>

* Create update-state-visualization-6836bd53e3a24891.yaml

Added release notes.

* Update test_graph_matplotlib_drawer.py

Included a test for the new features.

* fix test

* blacking

---------

Co-authored-by: Luciano Bello <bel@zurich.ibm.com>
  • Loading branch information
sg495 and 1ucian0 authored Mar 16, 2023
1 parent a85456d commit 0d15506
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 9 deletions.
6 changes: 4 additions & 2 deletions qiskit/visualization/bloch.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,9 @@ class Bloch:
Positions of +z and -z labels respectively.
"""

def __init__(self, fig=None, axes=None, view=None, figsize=None, background=False):
def __init__(
self, fig=None, axes=None, view=None, figsize=None, background=False, font_size=20
):

# Figure and axes
self._ext_fig = False
Expand Down Expand Up @@ -194,7 +196,7 @@ def __init__(self, fig=None, axes=None, view=None, figsize=None, background=Fals
# Color of fonts, default = 'black'
self.font_color = plt.rcParams["axes.labelcolor"]
# Size of fonts, default = 20
self.font_size = 20
self.font_size = font_size

# ---vector options---
# List of colors for Bloch vectors, default = ['b','g','r','y']
Expand Down
37 changes: 30 additions & 7 deletions qiskit/visualization/state_visualization.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,9 @@ def plot_state_hinton(


@_optionals.HAS_MATPLOTLIB.require_in_call
def plot_bloch_vector(bloch, title="", ax=None, figsize=None, coord_type="cartesian"):
def plot_bloch_vector(
bloch, title="", ax=None, figsize=None, coord_type="cartesian", font_size=None
):
"""Plot the Bloch sphere.
Plot a Bloch sphere with the specified coordinates, that can be given in both
Expand All @@ -204,6 +206,7 @@ def plot_bloch_vector(bloch, title="", ax=None, figsize=None, coord_type="cartes
figsize (tuple): Figure size in inches. Has no effect is passing ``ax``.
coord_type (str): a string that specifies coordinate type for bloch
(Cartesian or spherical), default is Cartesian
font_size (float): Font size.
Returns:
Figure: A matplotlib figure instance if ``ax = None``.
Expand Down Expand Up @@ -234,7 +237,7 @@ def plot_bloch_vector(bloch, title="", ax=None, figsize=None, coord_type="cartes

if figsize is None:
figsize = (5, 5)
B = Bloch(axes=ax)
B = Bloch(axes=ax, font_size=font_size)
if coord_type == "spherical":
r, theta, phi = bloch[0], bloch[1], bloch[2]
bloch[0] = r * np.sin(theta) * np.cos(phi)
Expand All @@ -253,7 +256,16 @@ def plot_bloch_vector(bloch, title="", ax=None, figsize=None, coord_type="cartes
@deprecate_arguments({"rho": "state"}, since="0.15.1")
@_optionals.HAS_MATPLOTLIB.require_in_call
def plot_bloch_multivector(
state, title="", figsize=None, *, rho=None, reverse_bits=False, filename=None
state,
title="",
figsize=None,
*,
rho=None,
reverse_bits=False,
filename=None,
font_size=None,
title_font_size=None,
title_pad=1,
):
r"""Plot a Bloch sphere for each qubit.
Expand All @@ -266,8 +278,11 @@ def plot_bloch_multivector(
Args:
state (Statevector or DensityMatrix or ndarray): an N-qubit quantum state.
title (str): a string that represents the plot title
figsize (tuple): Has no effect, here for compatibility only.
figsize (tuple): size of each individual Bloch sphere figure, in inches.
reverse_bits (bool): If True, plots qubits following Qiskit's convention [Default:False].
font_size (float): Font size for the Bloch ball figures.
title_font_size (float): Font size for the title.
title_pad (float): Padding for the title (suptitle `y` position is `y=1+title_pad/100`).
Returns:
matplotlib.Figure:
Expand Down Expand Up @@ -324,13 +339,21 @@ def plot_bloch_multivector(
_bloch_multivector_data(state)[::-1] if reverse_bits else _bloch_multivector_data(state)
)
num = len(bloch_data)
width, height = plt.figaspect(1 / num)
if figsize is not None:
width, height = figsize
width *= num
else:
width, height = plt.figaspect(1 / num)
default_title_font_size = font_size if font_size is not None else 16
title_font_size = title_font_size if title_font_size is not None else default_title_font_size
fig = plt.figure(figsize=(width, height))
for i in range(num):
pos = num - 1 - i if reverse_bits else i
ax = fig.add_subplot(1, num, i + 1, projection="3d")
plot_bloch_vector(bloch_data[i], "qubit " + str(pos), ax=ax, figsize=figsize)
fig.suptitle(title, fontsize=16, y=1.01)
plot_bloch_vector(
bloch_data[i], "qubit " + str(pos), ax=ax, figsize=figsize, font_size=font_size
)
fig.suptitle(title, fontsize=title_font_size, y=1.0 + title_pad / 100)
matplotlib_close_if_inline(fig)
if filename is None:
return fig
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
features:
- |
The ``figsize`` argument of
:obj:`~qiskit.visualization.plot_bloch_multivector` can now be used to
set a size for individual Bloch ball sub-plots: if there are ``num``
qubits and ``(w, h)`` is passed to ``figsize``, then the overall figure
width is set to ``num*w``, while the overall height is set to ``h``.
- |
A new ``font_size`` keyword argument for
:obj:`~qiskit.visualization.plot_bloch_multivector` can be used to
control the font size in Bloch ball sub-plots.
- |
New ``title_font_size`` and ``title_pad`` keyword arguments
for :obj:`~qiskit.visualization.plot_bloch_multivector` can be used to
control the font size of the overall title and its padding.
fixes:
- |
Previous to this release, the ``figsize`` argument of
:obj:`~qiskit.visualization.plot_bloch_multivector` was not used by the
visualization, making it impossible to change its size (e.g. to shrink
it for single-qubit states). This release fixes it by introducing a use
for the ``figsize`` argument.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 25 additions & 0 deletions test/ipynb/mpl/graph/test_graph_matplotlib_drawer.py
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,31 @@ def test_plot_coupling_map(self):
filename="coupling_map.png",
)

def test_plot_bloch_multivector_figsize_improvements(self):
"""test bloch sphere figsize, font_size, title_font_size and title_pad
See https://github.com/Qiskit/qiskit-terra/issues/7263
and https://github.com/Qiskit/qiskit-terra/pull/7264.
"""
circuit = QuantumCircuit(3)
circuit.h(1)
circuit.sxdg(2)

# getting the state using backend
backend = BasicAer.get_backend("statevector_simulator")
result = execute(circuit, backend).result()
state = result.get_statevector(circuit)

self.graph_state_drawer(
state=state,
output="bloch",
figsize=(3, 2),
font_size=10,
title="|0+R> state",
title_font_size=14,
title_pad=8,
filename="bloch_multivector_figsize_improvements.png",
)


if __name__ == "__main__":
unittest.main(verbosity=1)

0 comments on commit 0d15506

Please sign in to comment.