From 482ed81f458c31f38497717276451d860c024c7f Mon Sep 17 00:00:00 2001 From: Hunter Kemeny <43501602+hunterkemeny@users.noreply.github.com> Date: Wed, 24 Jan 2024 15:11:26 -0500 Subject: [PATCH 1/6] Deprecate visualization code --- ...recate-visualization-code-8303626254b79abe.yaml | 14 ++++++++++++++ qiskit/visualization/circuit/_utils.py | 9 ++------- qiskit/visualization/counts_visualization.py | 2 +- 3 files changed, 17 insertions(+), 8 deletions(-) create mode 100644 qiskit/releasenotes/notes/deprecate-visualization-code-8303626254b79abe.yaml diff --git a/qiskit/releasenotes/notes/deprecate-visualization-code-8303626254b79abe.yaml b/qiskit/releasenotes/notes/deprecate-visualization-code-8303626254b79abe.yaml new file mode 100644 index 000000000000..99a25b50485d --- /dev/null +++ b/qiskit/releasenotes/notes/deprecate-visualization-code-8303626254b79abe.yaml @@ -0,0 +1,14 @@ + +deprecations: + - | + Deprecated visualization code (set pending=False). + + For :func:`.plot_histogram` visualization: Passing :class:`.QuasiDistribution`, + :class:`.ProbDistribution`, or a distribution dictionary to the `data` argument is deprecated. + If you would like to plot a histogram from a :class:`.QuasiDistribution`, + :class:`.ProbDistribution`, or a distribution dictionary you should be using the + :func:`.plot_distribution` function. + + Also removed reverse-bits argument deprecation from + -- :func:`.get_bit_get_index` + -- :func:`.get_condition_label_val` diff --git a/qiskit/visualization/circuit/_utils.py b/qiskit/visualization/circuit/_utils.py index 252db40e51c5..38f8c81a80d8 100644 --- a/qiskit/visualization/circuit/_utils.py +++ b/qiskit/visualization/circuit/_utils.py @@ -31,7 +31,6 @@ from qiskit.circuit.tools import pi_check from qiskit.converters import circuit_to_dag from qiskit.utils import optionals as _optionals -from qiskit.utils.deprecation import deprecate_arg from ..exceptions import VisualizationError @@ -197,15 +196,13 @@ def get_bit_register(circuit, bit): return bit_loc.registers[0][0] if bit_loc.registers else None -@deprecate_arg("reverse_bits", since="0.22.0", package_name="qiskit-terra") -def get_bit_reg_index(circuit, bit, reverse_bits=None): +def get_bit_reg_index(circuit, bit): """Get the register for a bit if there is one, and the index of the bit from the top of the circuit, or the index of the bit within a register. Args: circuit (QuantumCircuit): the circuit being drawn bit (Qubit, Clbit): the bit to use to find the register and indexes - reverse_bits (bool): deprecated option to reverse order of the bits Returns: (ClassicalRegister, None): register associated with the bit @@ -285,15 +282,13 @@ def get_wire_label(drawer, register, index, layout=None, cregbundle=True): return wire_label -@deprecate_arg("reverse_bits", since="0.22.0", package_name="qiskit-terra") -def get_condition_label_val(condition, circuit, cregbundle, reverse_bits=None): +def get_condition_label_val(condition, circuit, cregbundle): """Get the label and value list to display a condition Args: condition (Union[Clbit, ClassicalRegister], int): classical condition circuit (QuantumCircuit): the circuit that is being drawn cregbundle (bool): if set True bundle classical registers - reverse_bits (bool): deprecated option to reverse order of the bits Returns: str: label to display for the condition diff --git a/qiskit/visualization/counts_visualization.py b/qiskit/visualization/counts_visualization.py index a0e4b64a4aa2..51bc88bedf22 100644 --- a/qiskit/visualization/counts_visualization.py +++ b/qiskit/visualization/counts_visualization.py @@ -66,7 +66,7 @@ def _is_deprecated_data_format(data) -> bool: since="0.22.0", additional_msg="Instead, use ``plot_distribution()``.", predicate=_is_deprecated_data_format, - pending=True, + pending=False, package_name="qiskit-terra", ) def plot_histogram( From a019dbcfe7d1c39a67fa35723b5c808242a446cc Mon Sep 17 00:00:00 2001 From: Hunter Kemeny <43501602+hunterkemeny@users.noreply.github.com> Date: Wed, 24 Jan 2024 21:03:49 -0500 Subject: [PATCH 2/6] Delete remove_bits from functions --- qiskit/visualization/circuit/_utils.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/qiskit/visualization/circuit/_utils.py b/qiskit/visualization/circuit/_utils.py index 38f8c81a80d8..79a81b675779 100644 --- a/qiskit/visualization/circuit/_utils.py +++ b/qiskit/visualization/circuit/_utils.py @@ -209,7 +209,6 @@ def get_bit_reg_index(circuit, bit): int: index of the bit from the top of the circuit int: index of the bit within the register, if there is a register """ - del reverse_bits bit_loc = circuit.find_bit(bit) bit_index = bit_loc.index register, reg_index = bit_loc.registers[0] if bit_loc.registers else (None, None) @@ -294,7 +293,6 @@ def get_condition_label_val(condition, circuit, cregbundle): str: label to display for the condition list(str): list of 1's and 0's indicating values of condition """ - del reverse_bits cond_is_bit = bool(isinstance(condition[0], Clbit)) cond_val = int(condition[1]) From 2ffa27841645263cc55fdf7bf0245d07f8877a15 Mon Sep 17 00:00:00 2001 From: Hunter Kemeny <43501602+hunterkemeny@users.noreply.github.com> Date: Wed, 24 Jan 2024 21:33:30 -0500 Subject: [PATCH 3/6] Fix releasenotes directory --- .../notes/deprecate-visualization-code-8303626254b79abe.yaml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {qiskit/releasenotes => releasenotes}/notes/deprecate-visualization-code-8303626254b79abe.yaml (100%) diff --git a/qiskit/releasenotes/notes/deprecate-visualization-code-8303626254b79abe.yaml b/releasenotes/notes/deprecate-visualization-code-8303626254b79abe.yaml similarity index 100% rename from qiskit/releasenotes/notes/deprecate-visualization-code-8303626254b79abe.yaml rename to releasenotes/notes/deprecate-visualization-code-8303626254b79abe.yaml From 2b31cf9b968d603008695c693bd22df92ee7f375 Mon Sep 17 00:00:00 2001 From: Matthew Treinish <mtreinish@kortar.org> Date: Thu, 1 Feb 2024 07:00:38 -0500 Subject: [PATCH 4/6] Restore deprecation of reverse_bits --- qiskit/visualization/circuit/_utils.py | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/qiskit/visualization/circuit/_utils.py b/qiskit/visualization/circuit/_utils.py index 79a81b675779..b491acfb510c 100644 --- a/qiskit/visualization/circuit/_utils.py +++ b/qiskit/visualization/circuit/_utils.py @@ -31,6 +31,7 @@ from qiskit.circuit.tools import pi_check from qiskit.converters import circuit_to_dag from qiskit.utils import optionals as _optionals +from qiskit.utils.deprecation import deprecate_arg from ..exceptions import VisualizationError @@ -196,19 +197,27 @@ def get_bit_register(circuit, bit): return bit_loc.registers[0][0] if bit_loc.registers else None -def get_bit_reg_index(circuit, bit): +@deprecate_arg( + "reverse_bits", + since="0.22.0", + package_name="qiskit-terra", + removal_timeline="in the Qiskit 1.0 release", +) +def get_bit_reg_index(circuit, bit, reverse_bits=None): """Get the register for a bit if there is one, and the index of the bit from the top of the circuit, or the index of the bit within a register. Args: circuit (QuantumCircuit): the circuit being drawn bit (Qubit, Clbit): the bit to use to find the register and indexes + reverse_bits (bool): deprecated option to reverse order of the bits Returns: (ClassicalRegister, None): register associated with the bit int: index of the bit from the top of the circuit int: index of the bit within the register, if there is a register """ + del reverse_bits bit_loc = circuit.find_bit(bit) bit_index = bit_loc.index register, reg_index = bit_loc.registers[0] if bit_loc.registers else (None, None) @@ -281,18 +290,26 @@ def get_wire_label(drawer, register, index, layout=None, cregbundle=True): return wire_label -def get_condition_label_val(condition, circuit, cregbundle): +@deprecate_arg( + "reverse_bits", + since="0.22.0", + package_name="qiskit-terra", + removal_timeline="in the Qiskit 1.0 release", +) +def get_condition_label_val(condition, circuit, cregbundle, reverse_bits=None): """Get the label and value list to display a condition Args: condition (Union[Clbit, ClassicalRegister], int): classical condition circuit (QuantumCircuit): the circuit that is being drawn cregbundle (bool): if set True bundle classical registers + reverse_bits (bool): deprecated option to reverse order of the bits Returns: str: label to display for the condition list(str): list of 1's and 0's indicating values of condition """ + del reverse_bits cond_is_bit = bool(isinstance(condition[0], Clbit)) cond_val = int(condition[1]) From 708ca5356b0fe4d79768fc7b3162caa6b7a8e92a Mon Sep 17 00:00:00 2001 From: Matthew Treinish <mtreinish@kortar.org> Date: Thu, 1 Feb 2024 07:00:45 -0500 Subject: [PATCH 5/6] Update releasenotes/notes/deprecate-visualization-code-8303626254b79abe.yaml --- ...cate-visualization-code-8303626254b79abe.yaml | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/releasenotes/notes/deprecate-visualization-code-8303626254b79abe.yaml b/releasenotes/notes/deprecate-visualization-code-8303626254b79abe.yaml index 99a25b50485d..59fe8d03a3cf 100644 --- a/releasenotes/notes/deprecate-visualization-code-8303626254b79abe.yaml +++ b/releasenotes/notes/deprecate-visualization-code-8303626254b79abe.yaml @@ -1,14 +1,10 @@ deprecations: - | - Deprecated visualization code (set pending=False). - - For :func:`.plot_histogram` visualization: Passing :class:`.QuasiDistribution`, - :class:`.ProbDistribution`, or a distribution dictionary to the `data` argument is deprecated. + Passing a :class:`.QuasiDistribution`, + :class:`.ProbDistribution`, or a distribution dictionary in for the ``data`` + argument of the :func:`.plot_histogram` visualization function is now + deprecated. Support for doing this will be removed in the Qiskit 1.0 release. If you would like to plot a histogram from a :class:`.QuasiDistribution`, - :class:`.ProbDistribution`, or a distribution dictionary you should be using the - :func:`.plot_distribution` function. - - Also removed reverse-bits argument deprecation from - -- :func:`.get_bit_get_index` - -- :func:`.get_condition_label_val` + :class:`.ProbDistribution`, or a distribution dictionary you should + use the :func:`.plot_distribution` function instead. From 99c180b8533a97439a7da08c6b06fcc5763b4093 Mon Sep 17 00:00:00 2001 From: Jake Lishman <jake.lishman@ibm.com> Date: Thu, 1 Feb 2024 12:54:41 +0000 Subject: [PATCH 6/6] Fix tests --- .../visualization/test_plot_histogram.py | 129 ++++++++++-------- 1 file changed, 69 insertions(+), 60 deletions(-) diff --git a/test/python/visualization/test_plot_histogram.py b/test/python/visualization/test_plot_histogram.py index 7c530851326d..1414619a0610 100644 --- a/test/python/visualization/test_plot_histogram.py +++ b/test/python/visualization/test_plot_histogram.py @@ -17,6 +17,7 @@ from collections import Counter from qiskit.visualization import plot_histogram +from qiskit.result import QuasiDistribution, ProbDistribution from qiskit.utils import optionals from .visualization import QiskitVisualizationTestCase @@ -33,19 +34,19 @@ class TestPlotHistogram(QiskitVisualizationTestCase): def test_different_counts_lengths(self): """Test plotting two different length dists works""" exact_dist = { - "000000": 0.015624999999999986, - "000001": 0.015624999999999986, - "000011": 0.031249999999999965, - "000111": 0.06249999999999992, - "100000": 0.015624999999999986, - "100001": 0.015624999999999986, - "100011": 0.031249999999999965, - "100111": 0.06249999999999992, - "110000": 0.031249999999999965, - "110001": 0.031249999999999965, - "110011": 0.06249999999999992, - "110111": 0.12499999999999982, - "111111": 0.4999999999999991, + "000000": 1, + "000001": 1, + "000011": 2, + "000111": 4, + "100000": 1, + "100001": 1, + "100011": 2, + "100111": 4, + "110000": 2, + "110001": 2, + "110011": 4, + "110111": 10, + "111111": 32, } raw_dist = { @@ -131,72 +132,72 @@ def test_with_number_to_keep_multiple_executions(self): def test_with_number_to_keep_multiple_executions_correct_image(self): """Test plotting using number_to_keep with multiple executions""" data_noisy = { - "00000": 0.22, - "00001": 0.003, - "00010": 0.005, - "00011": 0.0, - "00100": 0.004, - "00101": 0.001, - "00110": 0.004, - "00111": 0.001, - "01000": 0.005, - "01001": 0.0, - "01010": 0.002, - "01011": 0.0, - "01100": 0.225, - "01101": 0.001, - "01110": 0.003, - "01111": 0.003, - "10000": 0.012, - "10001": 0.002, - "10010": 0.001, - "10011": 0.001, - "10100": 0.247, - "10101": 0.004, - "10110": 0.003, - "10111": 0.001, - "11000": 0.225, - "11001": 0.005, - "11010": 0.002, - "11011": 0.0, - "11100": 0.015, - "11101": 0.004, - "11110": 0.001, - "11111": 0.0, + "00000": 22, + "00001": 3, + "00010": 5, + "00011": 0, + "00100": 4, + "00101": 1, + "00110": 4, + "00111": 1, + "01000": 5, + "01001": 0, + "01010": 2, + "01011": 0, + "01100": 225, + "01101": 1, + "01110": 3, + "01111": 3, + "10000": 12, + "10001": 2, + "10010": 1, + "10011": 1, + "10100": 247, + "10101": 4, + "10110": 3, + "10111": 1, + "11000": 225, + "11001": 5, + "11010": 2, + "11011": 0, + "11100": 15, + "11101": 4, + "11110": 1, + "11111": 0, } data_ideal = { - "00000": 0.25, + "00000": 25, "00001": 0, "00010": 0, "00011": 0, "00100": 0, "00101": 0, "00110": 0, - "00111": 0.0, - "01000": 0.0, + "00111": 0, + "01000": 0, "01001": 0, - "01010": 0.0, - "01011": 0.0, - "01100": 0.25, + "01010": 0, + "01011": 0, + "01100": 25, "01101": 0, "01110": 0, "01111": 0, "10000": 0, "10001": 0, - "10010": 0.0, - "10011": 0.0, - "10100": 0.25, + "10010": 0, + "10011": 0, + "10100": 25, "10101": 0, "10110": 0, "10111": 0, - "11000": 0.25, + "11000": 25, "11001": 0, "11010": 0, "11011": 0, - "11100": 0.0, + "11100": 0, "11101": 0, "11110": 0, - "11111": 0.0, + "11111": 0, } data_ref_noisy = dict(Counter(data_noisy).most_common(5)) data_ref_noisy["rest"] = sum(data_noisy.values()) - sum(data_ref_noisy.values()) @@ -214,11 +215,10 @@ def test_with_number_to_keep_multiple_executions_correct_image(self): mpl.pyplot.close(figure_ref) mpl.pyplot.close(figure_truncated) - @unittest.skipUnless(optionals.HAS_MATPLOTLIB, "matplotlib not available.") def test_number_of_items_in_legend_with_data_starting_with_zero(self): """Test legend if there's a 0 value at the first item of the dataset""" - dist_1 = {"0": 0.369, "1": 0.13975} - dist_2 = {"0": 0, "1": 0.48784} + dist_1 = {"0": 369, "1": 140} + dist_2 = {"0": 0, "1": 488} legend = ["lengend_1", "lengend_2"] plot = plot_histogram([dist_1, dist_2], legend=legend) self.assertEqual( @@ -227,6 +227,15 @@ def test_number_of_items_in_legend_with_data_starting_with_zero(self): "Plot should have the same number of legend items as defined", ) + def test_deprecation(self): + """Test that passing `QuasiDist`, `ProbDist` or a dict of floats is deprecated.""" + with self.assertWarns(DeprecationWarning): + plot_histogram(QuasiDistribution({"00": 1.0})) + with self.assertWarns(DeprecationWarning): + plot_histogram(ProbDistribution({"00": 1.0})) + with self.assertWarns(DeprecationWarning): + plot_histogram({"00": 1.0}) + if __name__ == "__main__": unittest.main(verbosity=2)