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

Update qsphere plots to show state labels and phases #4384

Merged
merged 12 commits into from
May 13, 2020
63 changes: 49 additions & 14 deletions qiskit/visualization/state_visualization.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import numpy as np
from scipy import linalg
from qiskit.quantum_info.operators.pauli import pauli_group, Pauli
from qiskit.circuit.tools.pi_check import pi_check
from .matplotlib import HAS_MATPLOTLIB

if HAS_MATPLOTLIB:
Expand Down Expand Up @@ -630,7 +631,8 @@ def phase_to_rgb(complex_number):
return rgb


def plot_state_qsphere(rho, figsize=None, ax=None):
def plot_state_qsphere(rho, figsize=None, ax=None, show_state_labels=True,
show_state_phases=True, use_degrees=True):
"""Plot the qsphere representation of a quantum state.
Here, the size of the points is proportional to the probability
of the corresponding term in the state and the color represents
Expand All @@ -644,6 +646,12 @@ def plot_state_qsphere(rho, figsize=None, ax=None):
the visualization output. If none is specified a new matplotlib
Figure will be created and used. Additionally, if specified there
will be no returned Figure since it is redundant.
show_state_labels (bool): An optional boolean indicating whether to
show labels for each basis state.
show_state_phases (bool): An optional boolean indicating whether to
show the phase for each basis state.
use_degrees (bool): An optional boolean indicating whether to use
radians or degrees for the phase values in the plot.

Returns:
Figure: A matplotlib figure instance if the ``ax`` kwag is not set
Expand Down Expand Up @@ -774,6 +782,24 @@ def plot_state_qsphere(rho, figsize=None, ax=None):
if yvalue >= 0.1:
alfa = 1.0 - yvalue

if prob > 0 and show_state_labels:
rprime = 1.3
angle_theta = np.arctan2(np.sqrt(1 - zvalue ** 2), zvalue)
xvalue_text = rprime * np.sin(angle_theta) * np.cos(angle)
yvalue_text = rprime * np.sin(angle_theta) * np.sin(angle)
zvalue_text = rprime * np.cos(angle_theta)
element_text = '$\\vert' + element + '\\rangle$'
if show_state_phases:
element_angle = (np.angle(state[i]) + (np.pi * 4)) % (np.pi * 2)
if use_degrees:
element_text += '\n$%.1f^\\circ$' % (element_angle * 180/np.pi)
else:
element_angle = pi_check(element_angle, ndigits=3, output='latex')
print(element_angle)
jaygambetta marked this conversation as resolved.
Show resolved Hide resolved
element_text += '\n$%s$' % (element_angle)
ax.text(xvalue_text, yvalue_text, zvalue_text, element_text,
ha='center', va='center', size=12)

ax.plot([xvalue], [yvalue], [zvalue],
markerfacecolor=colorstate,
markeredgecolor=colorstate,
Expand Down Expand Up @@ -807,21 +833,30 @@ def plot_state_qsphere(rho, figsize=None, ax=None):
ax2 = fig.add_subplot(gs[2:, 2:])
ax2.pie(theta, colors=sns.color_palette("hls", n), radius=0.75)
ax2.add_artist(Circle((0, 0), 0.5, color='white', zorder=1))
ax2.text(0, 0, 'Phase', horizontalalignment='center',
verticalalignment='center', fontsize=14)

offset = 0.95 # since radius of sphere is one.

ax2.text(offset, 0, r'$0$', horizontalalignment='center',
verticalalignment='center', fontsize=14)
ax2.text(0, offset, r'$\pi/2$', horizontalalignment='center',
verticalalignment='center', fontsize=14)

ax2.text(-offset, 0, r'$\pi$', horizontalalignment='center',
verticalalignment='center', fontsize=14)

ax2.text(0, -offset, r'$3\pi/2$', horizontalalignment='center',
verticalalignment='center', fontsize=14)
if use_degrees:
aasfaw marked this conversation as resolved.
Show resolved Hide resolved
ax2.text(0, 0, 'Phase\n(Deg)', horizontalalignment='center',
verticalalignment='center', fontsize=14)
ax2.text(offset, 0, r'0', horizontalalignment='center',
verticalalignment='center', fontsize=14)
ax2.text(0, offset, r'90', horizontalalignment='center',
verticalalignment='center', fontsize=14)
ax2.text(-offset, 0, r'180 ', horizontalalignment='center',
verticalalignment='center', fontsize=14)
ax2.text(0, -offset, r'270', horizontalalignment='center',
verticalalignment='center', fontsize=14)
else:
ax2.text(0, 0, 'Phase', horizontalalignment='center',
verticalalignment='center', fontsize=14)
ax2.text(offset, 0, r'$0$', horizontalalignment='center',
verticalalignment='center', fontsize=14)
ax2.text(0, offset, r'$\pi/2$', horizontalalignment='center',
verticalalignment='center', fontsize=14)
ax2.text(-offset, 0, r'$\pi$', horizontalalignment='center',
verticalalignment='center', fontsize=14)
ax2.text(0, -offset, r'$3\pi/2$', horizontalalignment='center',
verticalalignment='center', fontsize=14)

if return_fig:
if get_backend() in ['module://ipykernel.pylab.backend_inline',
Expand Down