Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new parameters in plot_bloch_multivector: figsize, font_size, and title_font_size #7264

Merged
merged 14 commits into from
Mar 17, 2023
Merged
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)