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 plot_wigner_sphere and delete matrix_histogram_complex #2193

Merged
merged 37 commits into from
Jul 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
7fef759
make plot_wigner_sphere user-friendly
tamakoshi2001 Jul 10, 2023
441ccd5
minor bagfix
tamakoshi2001 Jul 10, 2023
10ef557
delete arguments which users can set
tamakoshi2001 Jul 10, 2023
eb9cfcd
change matrix_histogram
tamakoshi2001 Jul 10, 2023
9bd647b
change matrix_histogram; change arguments to follow pep8
tamakoshi2001 Jul 10, 2023
81e6b89
add threshold
tamakoshi2001 Jul 10, 2023
b5f481f
add colorbar label
tamakoshi2001 Jul 10, 2023
ab5f0e5
add azim and elev
tamakoshi2001 Jul 10, 2023
c682823
refactoring
tamakoshi2001 Jul 10, 2023
0351ee5
reflection is optional
tamakoshi2001 Jul 10, 2023
65731c8
edit docstring
tamakoshi2001 Jul 10, 2023
36cb021
update arguments and error status
tamakoshi2001 Jul 11, 2023
394ab6d
minor change
tamakoshi2001 Jul 11, 2023
27ab9e9
add default values
tamakoshi2001 Jul 11, 2023
062c1fa
update on threshold option
tamakoshi2001 Jul 11, 2023
d6cd8da
pep8
tamakoshi2001 Jul 11, 2023
a0feb2d
minor fix
tamakoshi2001 Jul 11, 2023
b4c005b
minor fix
tamakoshi2001 Jul 11, 2023
6ada27e
replace matrix_histogram_complex with matrix_histogram
tamakoshi2001 Jul 12, 2023
1e0d02f
bugfix
tamakoshi2001 Jul 12, 2023
477926e
towncrier
tamakoshi2001 Jul 12, 2023
cc953e6
delete matrix_histogram_complex from text
tamakoshi2001 Jul 13, 2023
5991da7
pep8
tamakoshi2001 Jul 13, 2023
e9e776c
docstring warning
tamakoshi2001 Jul 13, 2023
eed69ab
add indentation
tamakoshi2001 Jul 14, 2023
03256ef
indent
tamakoshi2001 Jul 14, 2023
b2cdd69
pep8
tamakoshi2001 Jul 14, 2023
f996c0f
add pytest
tamakoshi2001 Jul 16, 2023
e652b3f
add pytest
tamakoshi2001 Jul 16, 2023
10cd390
add pytest
tamakoshi2001 Jul 16, 2023
fef43f4
add pytest
tamakoshi2001 Jul 16, 2023
87d9023
bugfix
tamakoshi2001 Jul 17, 2023
c24db08
add pytest
tamakoshi2001 Jul 17, 2023
37add2e
changes for review
tamakoshi2001 Jul 18, 2023
1712eca
Merge branch 'master' into edit_functions_in_visualization.py
tamakoshi2001 Jul 18, 2023
d95a1a7
resolve conflict
tamakoshi2001 Jul 18, 2023
22f94fa
add indent
tamakoshi2001 Jul 19, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/apidoc/functions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ Graphs and Visualization
------------------------

.. automodule:: qutip.visualization
:members: hinton, matrix_histogram, matrix_histogram_complex, plot_energy_levels, plot_fock_distribution, plot_wigner, sphereplot, plot_schmidt, plot_qubism, plot_expectation_values, plot_wigner_sphere, plot_spin_distribution
:members: hinton, matrix_histogram, plot_energy_levels, plot_fock_distribution, plot_wigner, sphereplot, plot_schmidt, plot_qubism, plot_expectation_values, plot_wigner_sphere, plot_spin_distribution
:undoc-members:

.. automodule:: qutip.orbital
Expand Down
1 change: 1 addition & 0 deletions doc/changes/2193.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
changed arguments and applied colorblind_safe to plot_wigner_sphere and matrix_histogram in visualization.py by Yuji Tamakoshi
7 changes: 3 additions & 4 deletions doc/guide/guide-visualization.rst
Original file line number Diff line number Diff line change
Expand Up @@ -281,10 +281,9 @@ structure and relative importance of various elements.

QuTiP offers a few functions for quickly visualizing matrix data in the
form of histograms, :func:`qutip.visualization.matrix_histogram` and
:func:`qutip.visualization.matrix_histogram_complex`, and as Hinton diagram of weighted
squares, :func:`qutip.visualization.hinton`. These functions takes a
:class:`qutip.Qobj` as first argument, and optional arguments to, for
example, set the axis labels and figure title (see the function's documentation
as Hinton diagram of weighted squares, :func:`qutip.visualization.hinton`.
These functions takes a :class:`qutip.Qobj` as first argument, and optional arguments to,
for example, set the axis labels and figure title (see the function's documentation
for details).

For example, to illustrate the use of :func:`qutip.visualization.matrix_histogram`,
Expand Down
148 changes: 146 additions & 2 deletions qutip/tests/test_visualization.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
def test_cyclic():
qutip.settings.colorblind_safe = True
rho = qutip.rand_dm(5)

fig, ax = qutip.hinton(rho, color_style='phase')
plt.close()

qutip.settings.colorblind_safe = False

assert isinstance(fig, mpl.figure.Figure)
Expand All @@ -19,8 +21,10 @@ def test_cyclic():
def test_diverging():
qutip.settings.colorblind_safe = True
rho = qutip.rand_dm(5)

fig, ax = qutip.hinton(rho)
plt.close()

qutip.settings.colorblind_safe = False

assert isinstance(fig, mpl.figure.Figure)
Expand All @@ -35,6 +39,7 @@ def test_sequential():
fig, ax = qutip.sphereplot(theta, phi,
qutip.orbital(theta, phi, qutip.basis(3, 0)).T)
plt.close()

qutip.settings.colorblind_safe = False

assert isinstance(fig, mpl.figure.Figure)
Expand Down Expand Up @@ -64,22 +69,39 @@ def test_is_fig_and_ax(f, a, projection):
if not f:
fig = None

rho = qutip.rand_dm(5)
fig, ax = qutip.plot_wigner(rho, projection=projection,
fig=fig, ax=ax)
plt.close()

assert isinstance(fig, mpl.figure.Figure)
assert isinstance(ax, mpl.axes.Axes)


def test_set_ticklabels():
rho = qutip.rand_dm(5)
text = "got 1 ticklabels but needed 5"

with pytest.raises(Exception) as exc_info:
fig, ax = qutip.hinton(rho, x_basis=[1])
assert str(exc_info.value) == text


@pytest.mark.parametrize('args', [
({'reflections': True}),
({'cmap': mpl.cm.cividis}),
({'colorbar': False}),
])
def test_plot_wigner_sphere(args):
psi = qutip.rand_ket(5)
wigner = qutip.wigner_transform(psi, 2, False, 50, ["x"])

fig, ax = qutip.plot_wigner_sphere(wigner, **args)
plt.close()

assert isinstance(fig, mpl.figure.Figure)
assert isinstance(ax, mpl.axes.Axes)


def to_oper_bra(oper):
return qutip.operator_to_vector(oper).dag()

Expand Down Expand Up @@ -120,6 +142,7 @@ def test_hinton1():
def test_hinton_ValueError0():
text = "Input quantum object must be an operator or superoperator."
rho = qutip.basis(2, 0)

with pytest.raises(ValueError) as exc_info:
fig, ax = qutip.hinton(rho)
assert str(exc_info.value) == text
Expand All @@ -133,6 +156,7 @@ def test_hinton_ValueError0():
])
def test_hinton_ValueError1(transform, args, error_message):
rho = transform(qutip.rand_dm(5))

with pytest.raises(ValueError) as exc_info:
fig, ax = qutip.hinton(rho, **args)
assert str(exc_info.value) == error_message
Expand All @@ -155,6 +179,122 @@ def test_sphereplot(args):
assert isinstance(ax, mpl.axes.Axes)


@pytest.mark.parametrize('response', [
('normal'),
('error')
])
def test_update_yaxis(response):
if response == 'normal':
fig, ax = qutip.matrix_histogram(np.zeros((3, 3)))
plt.close()

assert isinstance(fig, mpl.figure.Figure)
assert isinstance(ax, mpl.axes.Axes)
else:
text = "got 1 ylabels but needed 5"

with pytest.raises(ValueError) as exc_info:
fig, ax = qutip.matrix_histogram(qutip.rand_dm(5),
y_basis=[1])

assert str(exc_info.value) == text


@pytest.mark.parametrize('response', [
('normal'),
('error')
])
def test_update_xaxis(response):
if response == 'normal':
fig, ax = qutip.matrix_histogram(np.zeros((3, 3)))
plt.close()

assert isinstance(fig, mpl.figure.Figure)
assert isinstance(ax, mpl.axes.Axes)
else:
text = "got 1 xlabels but needed 5"

with pytest.raises(ValueError) as exc_info:
fig, ax = qutip.matrix_histogram(qutip.rand_dm(5),
x_basis=[1])
assert str(exc_info.value) == text


def test_get_matrix_components():
text = "got an unexpected argument, error for bar_style"

with pytest.raises(ValueError) as exc_info:
fig, ax = qutip.matrix_histogram(qutip.rand_dm(5),
bar_style='error')
assert str(exc_info.value) == text


@pytest.mark.parametrize('args', [
({'options': {'stick': True, 'azim': 45}}),
({'options': {'stick': True, 'azim': 135}}),
({'options': {'stick': True, 'azim': 225}}),
({'options': {'stick': True, 'azim': 315}}),
])
def test_stick_to_planes(args):
rho = qutip.rand_dm(5)

fig, ax = qutip.matrix_histogram(rho, **args)
plt.close()

assert isinstance(fig, mpl.figure.Figure)
assert isinstance(ax, mpl.axes.Axes)


@pytest.mark.parametrize('args', [
({}),
({'options': {'zticks': [1]}}),
({'x_basis': [1, 2, 3, 4, 5]}),
({'y_basis': [1, 2, 3, 4, 5]}),
({'limits': [0, 1]}),
({'color_limits': [0, 1]}),
({'color_style': 'phase'}),
({'options': {'threshold': 0.1}}),
({'color_style': 'real', 'colorbar': True}),
({'color_style': 'img', 'colorbar': True}),
({'color_style': 'abs', 'colorbar': True}),
({'color_style': 'phase', 'colorbar': True}),
({'color_limits': [0, 1], 'color_style': 'phase', 'colorbar': True})
])
def test_matrix_histogram(args):
rho = qutip.rand_dm(5)

fig, ax = qutip.matrix_histogram(rho, **args)
plt.close()

assert isinstance(fig, mpl.figure.Figure)
assert isinstance(ax, mpl.axes.Axes)


def test_matrix_histogram_zeros():
rho = qutip.Qobj([[0, 0], [0, 0]])

fig, ax = qutip.matrix_histogram(rho)
plt.close()

assert isinstance(fig, mpl.figure.Figure)
assert isinstance(ax, mpl.axes.Axes)


@pytest.mark.parametrize('args, expected', [
({'options': 'error'}, ("options must be a dictionary")),
({'options': {'e1': '1', 'e2': '2'}},
("invalid key(s) found in options: e1, e2",
"invalid key(s) found in options: e2, e1")),
])
def test_matrix_histogram_ValueError(args, expected):
text = "options must be a dictionary"

with pytest.raises(ValueError) as exc_info:
fig, ax = qutip.matrix_histogram(qutip.rand_dm(5),
**args)
assert str(exc_info.value) in expected


@pytest.mark.parametrize('args', [
({'h_labels': ['H0', 'H0+Hint']}),
({'energy_levels': [-2, 0, 2]}),
Expand Down Expand Up @@ -224,7 +364,6 @@ def test_plot_wigner_ValueError():
rho = qutip.rand_dm(4)

fig, ax = qutip.plot_wigner(rho, projection=1)
plt.close()
assert str(exc_info.value) == text


Expand Down Expand Up @@ -300,6 +439,7 @@ def test_plot_spin_distribution_ValueError():
theta = np.linspace(0, np.pi, 50)
phi = np.linspace(0, 2 * np.pi, 50)
Q, THETA, PHI = qutip.spin_q_function(psi, theta, phi)

with pytest.raises(ValueError) as exc_info:
fig, ax = qutip.plot_spin_distribution(Q, THETA, PHI, projection=1)
assert str(exc_info.value) == text
Expand All @@ -311,6 +451,7 @@ def test_plot_spin_distribution_ValueError():
])
def test_complex_array_to_rgb(args):
Y = qutip.complex_array_to_rgb(np.zeros((3, 3)), **args)
plt.close()

assert isinstance(Y, np.ndarray)

Expand Down Expand Up @@ -351,6 +492,7 @@ def test_plot_qubism_Error(ket, args, expected):
state = qutip.ket("01")
else:
state = qutip.bra("01")

with pytest.raises(Exception) as exc_info:
fig, ax = qutip.plot_qubism(state, **args)
assert str(exc_info.value) == expected
Expand All @@ -360,6 +502,7 @@ def test_plot_qubism_dimension():
text = "For 'pairs_skewed' pairs of dimensions need to be the same."

ket = qutip.basis(3) & qutip.basis(2)

with pytest.raises(Exception) as exc_info:
qutip.plot_qubism(ket, how='pairs_skewed')
assert str(exc_info.value) == text
Expand All @@ -382,6 +525,7 @@ def test_plot_schmidt(args):
def test_plot_schmidt_Error():
state = qutip.bra("01")
text = "Schmidt plot works only for pure states, i.e. kets."

with pytest.raises(Exception) as exc_info:
fig, ax = qutip.plot_schmidt(state)
assert str(exc_info.value) == text
16 changes: 9 additions & 7 deletions qutip/tomography.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from numpy import hstack, real, imag
import scipy.linalg as la
from . import tensor, spre, spost, stack_columns, unstack_columns
from .visualization import matrix_histogram, matrix_histogram_complex
from .visualization import matrix_histogram
import itertools

try:
Expand Down Expand Up @@ -71,10 +71,11 @@ def qpt_plot(chi, lbls_list, title=None, fig=None, axes=None):
xlabels.append("".join([lbls_list[k][inds[k]]
for k in range(len(lbls_list))]))

matrix_histogram(real(chi), xlabels, xlabels,
title=r"real($\chi$)", limits=[-1, 1], ax=axes[0])
matrix_histogram(imag(chi), xlabels, xlabels,
title=r"imag($\chi$)", limits=[-1, 1], ax=axes[1])
matrix_histogram(real(chi), xlabels, xlabels, limits=[-1, 1], ax=axes[0])
axes[0].set_title(r"real($\chi$)")

matrix_histogram(imag(chi), xlabels, xlabels, limits=[-1, 1], ax=axes[1])
axes[1].set_title(r"imag($\chi$)")

if title and fig:
fig.suptitle(title)
Expand Down Expand Up @@ -132,8 +133,9 @@ def qpt_plot_combined(chi, lbls_list, title=None,
if not title:
title = r"$\chi$"

matrix_histogram_complex(chi, xlabels, xlabels, ax=ax,
threshold=threshold)
matrix_histogram(chi, xlabels, xlabels, bar_style='abs',
color_style='phase',
options={'threshold': threshold}, ax=ax)
ax.set_title(title)

return fig, ax
Expand Down