diff --git a/.azure/test-linux.yml b/.azure/test-linux.yml index 807246a85191..eb4f8517644d 100644 --- a/.azure/test-linux.yml +++ b/.azure/test-linux.yml @@ -177,6 +177,7 @@ jobs: image_tests/bin/python -m pip install -U \ -c constraints.txt \ -r requirements.txt \ + -r requirements-dev.txt \ -e ".[visualization]" sudo apt-get update sudo apt-get install -y graphviz pandoc @@ -185,10 +186,47 @@ jobs: env: SETUPTOOLS_ENABLE_FEATURES: "legacy-editable" - - bash: image_tests/bin/python -m unittest discover -v test/ipynb + - bash: image_tests/bin/python -m unittest discover -v test/visual displayName: 'Run image test' env: # Needed to suppress a warning in jupyter-core 5.x by eagerly migrating to # a new internal interface that will be the default in jupyter-core 6.x. # This variable should become redundant on release of jupyter-core 6. JUPYTER_PLATFORM_DIRS: 1 + + - task: ArchiveFiles@2 + displayName: Archive visual test failure diffs + inputs: + rootFolderOrFile: 'test/visual/mpl/visual_test_failures' + includeRootFolder: false + archiveType: tar + archiveFile: '$(Build.ArtifactStagingDirectory)/visual_test_failures.tar.gz' + verbose: true + condition: failed() + + - task: ArchiveFiles@2 + displayName: Archive circuit results + inputs: + rootFolderOrFile: 'test/visual/mpl/circuit/circuit_results' + archiveType: tar + archiveFile: '$(Build.ArtifactStagingDirectory)/circuit_results.tar.gz' + verbose: true + condition: failed() + + - task: ArchiveFiles@2 + displayName: Archive graph results + inputs: + rootFolderOrFile: 'test/visual/mpl/graph/graph_results' + archiveType: tar + archiveFile: '$(Build.ArtifactStagingDirectory)/graph_results.tar.gz' + verbose: true + condition: failed() + + - task: PublishBuildArtifacts@1 + displayName: 'Publish image test failure diffs' + inputs: + pathtoPublish: '$(Build.ArtifactStagingDirectory)' + artifactName: 'image_test_failure_img_diffs' + Parallel: true + ParallelCount: 8 + condition: failed() diff --git a/qiskit/visualization/state_visualization.py b/qiskit/visualization/state_visualization.py index 0c11254a7fb1..4651f6fce225 100644 --- a/qiskit/visualization/state_visualization.py +++ b/qiskit/visualization/state_visualization.py @@ -515,6 +515,9 @@ def plot_state_city( min_dzi = np.min(dzi) max_dzi = np.max(dzi) + # There seems to be a rounding error in which some zero bars are negative + dzr = np.clip(dzr, 0, None) + if ax1 is not None: fc1 = generate_facecolors(xpos, ypos, zpos, dx, dy, dzr, color[0]) for idx, cur_zpos in enumerate(zpos): diff --git a/test/ipynb/mpl/circuit/__init__.py b/test/ipynb/mpl/circuit/__init__.py deleted file mode 100644 index faf6e72c621b..000000000000 --- a/test/ipynb/mpl/circuit/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -# This code is part of Qiskit. -# -# (C) Copyright IBM 2020. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -"""Image comparison test for MPL circuit drawer. -You can generate the image references with Binder -in https://mybinder.org/v2/gh///?urlpath=apps/test/ipynb/mpl_tester.ipynb -""" diff --git a/test/ipynb/mpl/circuit/references/6095.png b/test/ipynb/mpl/circuit/references/6095.png deleted file mode 100644 index 50d8f6e94bea..000000000000 Binary files a/test/ipynb/mpl/circuit/references/6095.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/barrier_label.png b/test/ipynb/mpl/circuit/references/barrier_label.png deleted file mode 100644 index c1db46dccfdd..000000000000 Binary files a/test/ipynb/mpl/circuit/references/barrier_label.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/big_gates.png b/test/ipynb/mpl/circuit/references/big_gates.png deleted file mode 100644 index 8fcd48c44054..000000000000 Binary files a/test/ipynb/mpl/circuit/references/big_gates.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/bit_conditional_bundle.png b/test/ipynb/mpl/circuit/references/bit_conditional_bundle.png deleted file mode 100644 index 3397ad9fd20c..000000000000 Binary files a/test/ipynb/mpl/circuit/references/bit_conditional_bundle.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/bit_conditional_no_bundle.png b/test/ipynb/mpl/circuit/references/bit_conditional_no_bundle.png deleted file mode 100644 index c7853fe8a700..000000000000 Binary files a/test/ipynb/mpl/circuit/references/bit_conditional_no_bundle.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/bw.png b/test/ipynb/mpl/circuit/references/bw.png deleted file mode 100644 index 4c9c2bc18d1e..000000000000 Binary files a/test/ipynb/mpl/circuit/references/bw.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/calibrations.png b/test/ipynb/mpl/circuit/references/calibrations.png deleted file mode 100644 index 4b12996adf08..000000000000 Binary files a/test/ipynb/mpl/circuit/references/calibrations.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/calibrations_with_control_gates.png b/test/ipynb/mpl/circuit/references/calibrations_with_control_gates.png deleted file mode 100644 index 4d2bb93dbe03..000000000000 Binary files a/test/ipynb/mpl/circuit/references/calibrations_with_control_gates.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/calibrations_with_rzz_and_rxx.png b/test/ipynb/mpl/circuit/references/calibrations_with_rzz_and_rxx.png deleted file mode 100644 index 64919cad1c37..000000000000 Binary files a/test/ipynb/mpl/circuit/references/calibrations_with_rzz_and_rxx.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/calibrations_with_swap_and_reset.png b/test/ipynb/mpl/circuit/references/calibrations_with_swap_and_reset.png deleted file mode 100644 index 7a5c6fb4e340..000000000000 Binary files a/test/ipynb/mpl/circuit/references/calibrations_with_swap_and_reset.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/cnot.png b/test/ipynb/mpl/circuit/references/cnot.png deleted file mode 100644 index f794c8a6ede9..000000000000 Binary files a/test/ipynb/mpl/circuit/references/cnot.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/cond_bits_reverse.png b/test/ipynb/mpl/circuit/references/cond_bits_reverse.png deleted file mode 100644 index 5499e9ec9667..000000000000 Binary files a/test/ipynb/mpl/circuit/references/cond_bits_reverse.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/creg_initial_false.png b/test/ipynb/mpl/circuit/references/creg_initial_false.png deleted file mode 100644 index bea68fb829ba..000000000000 Binary files a/test/ipynb/mpl/circuit/references/creg_initial_false.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/creg_initial_true.png b/test/ipynb/mpl/circuit/references/creg_initial_true.png deleted file mode 100644 index 7efd7618836f..000000000000 Binary files a/test/ipynb/mpl/circuit/references/creg_initial_true.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/cswap_rzz.png b/test/ipynb/mpl/circuit/references/cswap_rzz.png deleted file mode 100644 index 2a63c5b2d66f..000000000000 Binary files a/test/ipynb/mpl/circuit/references/cswap_rzz.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/ctrl_labels.png b/test/ipynb/mpl/circuit/references/ctrl_labels.png deleted file mode 100644 index 6086990c2c29..000000000000 Binary files a/test/ipynb/mpl/circuit/references/ctrl_labels.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/cz.png b/test/ipynb/mpl/circuit/references/cz.png deleted file mode 100644 index 7f2817abe25c..000000000000 Binary files a/test/ipynb/mpl/circuit/references/cz.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/empty_circut.png b/test/ipynb/mpl/circuit/references/empty_circut.png deleted file mode 100644 index 2a9eddb9a108..000000000000 Binary files a/test/ipynb/mpl/circuit/references/empty_circut.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/figwidth.png b/test/ipynb/mpl/circuit/references/figwidth.png deleted file mode 100644 index 1c3fd80eb3a2..000000000000 Binary files a/test/ipynb/mpl/circuit/references/figwidth.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/fold_4.png b/test/ipynb/mpl/circuit/references/fold_4.png deleted file mode 100644 index 98de2f5d5d05..000000000000 Binary files a/test/ipynb/mpl/circuit/references/fold_4.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/fold_minus1.png b/test/ipynb/mpl/circuit/references/fold_minus1.png deleted file mode 100644 index 3e3e937a9e28..000000000000 Binary files a/test/ipynb/mpl/circuit/references/fold_minus1.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/fold_with_conditions.png b/test/ipynb/mpl/circuit/references/fold_with_conditions.png deleted file mode 100644 index 867904c733bd..000000000000 Binary files a/test/ipynb/mpl/circuit/references/fold_with_conditions.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/ghz_to_gate.png b/test/ipynb/mpl/circuit/references/ghz_to_gate.png deleted file mode 100644 index 0ef1a30fcd2a..000000000000 Binary files a/test/ipynb/mpl/circuit/references/ghz_to_gate.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/global_phase.png b/test/ipynb/mpl/circuit/references/global_phase.png deleted file mode 100644 index d975f13ee0d4..000000000000 Binary files a/test/ipynb/mpl/circuit/references/global_phase.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/idle_wires_barrier.png b/test/ipynb/mpl/circuit/references/idle_wires_barrier.png deleted file mode 100644 index 2bb7ab8f2fe1..000000000000 Binary files a/test/ipynb/mpl/circuit/references/idle_wires_barrier.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/init_reset.png b/test/ipynb/mpl/circuit/references/init_reset.png deleted file mode 100644 index cb86c9c1fd4a..000000000000 Binary files a/test/ipynb/mpl/circuit/references/init_reset.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/instruction_1q_1c.png b/test/ipynb/mpl/circuit/references/instruction_1q_1c.png deleted file mode 100644 index 5f342704f8c4..000000000000 Binary files a/test/ipynb/mpl/circuit/references/instruction_1q_1c.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/instruction_3q_3c_circ1.png b/test/ipynb/mpl/circuit/references/instruction_3q_3c_circ1.png deleted file mode 100644 index ef2c41d42775..000000000000 Binary files a/test/ipynb/mpl/circuit/references/instruction_3q_3c_circ1.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/instruction_3q_3c_circ2.png b/test/ipynb/mpl/circuit/references/instruction_3q_3c_circ2.png deleted file mode 100644 index 4d7f28e4f2fe..000000000000 Binary files a/test/ipynb/mpl/circuit/references/instruction_3q_3c_circ2.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/instruction_3q_3c_circ3.png b/test/ipynb/mpl/circuit/references/instruction_3q_3c_circ3.png deleted file mode 100644 index e52e30004b5c..000000000000 Binary files a/test/ipynb/mpl/circuit/references/instruction_3q_3c_circ3.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/iqx-dark_color.png b/test/ipynb/mpl/circuit/references/iqx-dark_color.png deleted file mode 100644 index 22efe4cc88c6..000000000000 Binary files a/test/ipynb/mpl/circuit/references/iqx-dark_color.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/iqx_color.png b/test/ipynb/mpl/circuit/references/iqx_color.png deleted file mode 100644 index e2dd042006e1..000000000000 Binary files a/test/ipynb/mpl/circuit/references/iqx_color.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/long_name.png b/test/ipynb/mpl/circuit/references/long_name.png deleted file mode 100644 index 6f3fd0ba9a5a..000000000000 Binary files a/test/ipynb/mpl/circuit/references/long_name.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/meas_condition.png b/test/ipynb/mpl/circuit/references/meas_condition.png deleted file mode 100644 index 9a066a606042..000000000000 Binary files a/test/ipynb/mpl/circuit/references/meas_condition.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/measure_cond_bits_false.png b/test/ipynb/mpl/circuit/references/measure_cond_bits_false.png deleted file mode 100644 index 35a6b8cfefe6..000000000000 Binary files a/test/ipynb/mpl/circuit/references/measure_cond_bits_false.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/measure_cond_bits_right.png b/test/ipynb/mpl/circuit/references/measure_cond_bits_right.png deleted file mode 100644 index a989598c53cd..000000000000 Binary files a/test/ipynb/mpl/circuit/references/measure_cond_bits_right.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/measure_cond_bits_true.png b/test/ipynb/mpl/circuit/references/measure_cond_bits_true.png deleted file mode 100644 index f13566ba1c7b..000000000000 Binary files a/test/ipynb/mpl/circuit/references/measure_cond_bits_true.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/measure_cond_false.png b/test/ipynb/mpl/circuit/references/measure_cond_false.png deleted file mode 100644 index e523faeac879..000000000000 Binary files a/test/ipynb/mpl/circuit/references/measure_cond_false.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/measure_cond_true.png b/test/ipynb/mpl/circuit/references/measure_cond_true.png deleted file mode 100644 index 1ef542b563f0..000000000000 Binary files a/test/ipynb/mpl/circuit/references/measure_cond_true.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/multi_underscore_false.png b/test/ipynb/mpl/circuit/references/multi_underscore_false.png deleted file mode 100644 index 2d2bbc7368b6..000000000000 Binary files a/test/ipynb/mpl/circuit/references/multi_underscore_false.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/multi_underscore_true.png b/test/ipynb/mpl/circuit/references/multi_underscore_true.png deleted file mode 100644 index c7c16523c05b..000000000000 Binary files a/test/ipynb/mpl/circuit/references/multi_underscore_true.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/no_barriers.png b/test/ipynb/mpl/circuit/references/no_barriers.png deleted file mode 100644 index 14bbee5d8e9e..000000000000 Binary files a/test/ipynb/mpl/circuit/references/no_barriers.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/no_op_circut.png b/test/ipynb/mpl/circuit/references/no_op_circut.png deleted file mode 100644 index 2de55fa20a62..000000000000 Binary files a/test/ipynb/mpl/circuit/references/no_op_circut.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/one_bit_regs.png b/test/ipynb/mpl/circuit/references/one_bit_regs.png deleted file mode 100644 index 5b89ba83728d..000000000000 Binary files a/test/ipynb/mpl/circuit/references/one_bit_regs.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/partial_layout.png b/test/ipynb/mpl/circuit/references/partial_layout.png deleted file mode 100644 index 3ab14f3e90bf..000000000000 Binary files a/test/ipynb/mpl/circuit/references/partial_layout.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/pauli_clifford.png b/test/ipynb/mpl/circuit/references/pauli_clifford.png deleted file mode 100644 index 20924257ae33..000000000000 Binary files a/test/ipynb/mpl/circuit/references/pauli_clifford.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/pi_in_param_expr.png b/test/ipynb/mpl/circuit/references/pi_in_param_expr.png deleted file mode 100644 index 7cdbb21d1cb7..000000000000 Binary files a/test/ipynb/mpl/circuit/references/pi_in_param_expr.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/plot_barriers_false.png b/test/ipynb/mpl/circuit/references/plot_barriers_false.png deleted file mode 100644 index 37dbdac15e77..000000000000 Binary files a/test/ipynb/mpl/circuit/references/plot_barriers_false.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/plot_barriers_true.png b/test/ipynb/mpl/circuit/references/plot_barriers_true.png deleted file mode 100644 index 7c68313c1831..000000000000 Binary files a/test/ipynb/mpl/circuit/references/plot_barriers_true.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/plot_partial_barrier.png b/test/ipynb/mpl/circuit/references/plot_partial_barrier.png deleted file mode 100644 index a54df5d2301d..000000000000 Binary files a/test/ipynb/mpl/circuit/references/plot_partial_barrier.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/r_gates.png b/test/ipynb/mpl/circuit/references/r_gates.png deleted file mode 100644 index 5cbcabd63887..000000000000 Binary files a/test/ipynb/mpl/circuit/references/r_gates.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/reg_conditional.png b/test/ipynb/mpl/circuit/references/reg_conditional.png deleted file mode 100644 index 0abce3f881fd..000000000000 Binary files a/test/ipynb/mpl/circuit/references/reg_conditional.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/registerless_one_bit.png b/test/ipynb/mpl/circuit/references/registerless_one_bit.png deleted file mode 100644 index 4da4c4920ee3..000000000000 Binary files a/test/ipynb/mpl/circuit/references/registerless_one_bit.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/reverse_bits.png b/test/ipynb/mpl/circuit/references/reverse_bits.png deleted file mode 100644 index bf71f0941fc3..000000000000 Binary files a/test/ipynb/mpl/circuit/references/reverse_bits.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/reverse_bits_cond_false.png b/test/ipynb/mpl/circuit/references/reverse_bits_cond_false.png deleted file mode 100644 index 6b05c229ce35..000000000000 Binary files a/test/ipynb/mpl/circuit/references/reverse_bits_cond_false.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/reverse_bits_cond_true.png b/test/ipynb/mpl/circuit/references/reverse_bits_cond_true.png deleted file mode 100644 index 810b9f85dc54..000000000000 Binary files a/test/ipynb/mpl/circuit/references/reverse_bits_cond_true.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/scale_default.png b/test/ipynb/mpl/circuit/references/scale_default.png deleted file mode 100644 index 7e0dcaa02334..000000000000 Binary files a/test/ipynb/mpl/circuit/references/scale_default.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/scale_double.png b/test/ipynb/mpl/circuit/references/scale_double.png deleted file mode 100644 index 46c9b2c10217..000000000000 Binary files a/test/ipynb/mpl/circuit/references/scale_double.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/scale_half.png b/test/ipynb/mpl/circuit/references/scale_half.png deleted file mode 100644 index e442ef2e7bc2..000000000000 Binary files a/test/ipynb/mpl/circuit/references/scale_half.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/sidetext_condition.png b/test/ipynb/mpl/circuit/references/sidetext_condition.png deleted file mode 100644 index c603118cb629..000000000000 Binary files a/test/ipynb/mpl/circuit/references/sidetext_condition.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/style_custom_gates.png b/test/ipynb/mpl/circuit/references/style_custom_gates.png deleted file mode 100644 index ad1ba2830009..000000000000 Binary files a/test/ipynb/mpl/circuit/references/style_custom_gates.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/subfont.png b/test/ipynb/mpl/circuit/references/subfont.png deleted file mode 100644 index ea060131541d..000000000000 Binary files a/test/ipynb/mpl/circuit/references/subfont.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/textbook_color.png b/test/ipynb/mpl/circuit/references/textbook_color.png deleted file mode 100644 index f353bc90d724..000000000000 Binary files a/test/ipynb/mpl/circuit/references/textbook_color.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/user_ax.png b/test/ipynb/mpl/circuit/references/user_ax.png deleted file mode 100644 index 2162bd5007d2..000000000000 Binary files a/test/ipynb/mpl/circuit/references/user_ax.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/user_style.png b/test/ipynb/mpl/circuit/references/user_style.png deleted file mode 100644 index a3a425671558..000000000000 Binary files a/test/ipynb/mpl/circuit/references/user_style.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/wide_params.png b/test/ipynb/mpl/circuit/references/wide_params.png deleted file mode 100644 index 7fc54abeef1c..000000000000 Binary files a/test/ipynb/mpl/circuit/references/wide_params.png and /dev/null differ diff --git a/test/ipynb/mpl/circuit/references/wire_order.png b/test/ipynb/mpl/circuit/references/wire_order.png deleted file mode 100644 index 5e83b48be564..000000000000 Binary files a/test/ipynb/mpl/circuit/references/wire_order.png and /dev/null differ diff --git a/test/ipynb/mpl/graph/references/16_qubit_gate_map.png b/test/ipynb/mpl/graph/references/16_qubit_gate_map.png deleted file mode 100644 index 36a39de2141a..000000000000 Binary files a/test/ipynb/mpl/graph/references/16_qubit_gate_map.png and /dev/null differ diff --git a/test/ipynb/mpl/graph/references/1_qubit_gate_map.png b/test/ipynb/mpl/graph/references/1_qubit_gate_map.png deleted file mode 100644 index 451e7455ebb3..000000000000 Binary files a/test/ipynb/mpl/graph/references/1_qubit_gate_map.png and /dev/null differ diff --git a/test/ipynb/mpl/graph/references/27_qubit_gate_map.png b/test/ipynb/mpl/graph/references/27_qubit_gate_map.png deleted file mode 100644 index 026b619de376..000000000000 Binary files a/test/ipynb/mpl/graph/references/27_qubit_gate_map.png and /dev/null differ diff --git a/test/ipynb/mpl/graph/references/5_qubit_gate_map.png b/test/ipynb/mpl/graph/references/5_qubit_gate_map.png deleted file mode 100644 index 8494f501220f..000000000000 Binary files a/test/ipynb/mpl/graph/references/5_qubit_gate_map.png and /dev/null differ diff --git a/test/ipynb/mpl/graph/references/65_qubit_gate_map.png b/test/ipynb/mpl/graph/references/65_qubit_gate_map.png deleted file mode 100644 index 57bf313974a2..000000000000 Binary files a/test/ipynb/mpl/graph/references/65_qubit_gate_map.png and /dev/null differ diff --git a/test/ipynb/mpl/graph/references/7_qubit_gate_map.png b/test/ipynb/mpl/graph/references/7_qubit_gate_map.png deleted file mode 100644 index 26b7f3e64e75..000000000000 Binary files a/test/ipynb/mpl/graph/references/7_qubit_gate_map.png and /dev/null differ diff --git a/test/ipynb/mpl/graph/references/bloch_multivector.png b/test/ipynb/mpl/graph/references/bloch_multivector.png deleted file mode 100644 index af1b1b1fc2bf..000000000000 Binary files a/test/ipynb/mpl/graph/references/bloch_multivector.png and /dev/null differ diff --git a/test/ipynb/mpl/graph/references/bloch_multivector_figsize_improvements.png b/test/ipynb/mpl/graph/references/bloch_multivector_figsize_improvements.png deleted file mode 100644 index c7e8b102ea0b..000000000000 Binary files a/test/ipynb/mpl/graph/references/bloch_multivector_figsize_improvements.png and /dev/null differ diff --git a/test/ipynb/mpl/graph/references/coupling_map.png b/test/ipynb/mpl/graph/references/coupling_map.png deleted file mode 100644 index 8494f501220f..000000000000 Binary files a/test/ipynb/mpl/graph/references/coupling_map.png and /dev/null differ diff --git a/test/ipynb/mpl/graph/references/figsize.png b/test/ipynb/mpl/graph/references/figsize.png deleted file mode 100644 index 6613a6884de2..000000000000 Binary files a/test/ipynb/mpl/graph/references/figsize.png and /dev/null differ diff --git a/test/ipynb/mpl/graph/references/font_color.png b/test/ipynb/mpl/graph/references/font_color.png deleted file mode 100644 index 0c50ef74c19a..000000000000 Binary files a/test/ipynb/mpl/graph/references/font_color.png and /dev/null differ diff --git a/test/ipynb/mpl/graph/references/hinton.png b/test/ipynb/mpl/graph/references/hinton.png deleted file mode 100644 index ee86630653f4..000000000000 Binary files a/test/ipynb/mpl/graph/references/hinton.png and /dev/null differ diff --git a/test/ipynb/mpl/graph/references/histogram.png b/test/ipynb/mpl/graph/references/histogram.png deleted file mode 100644 index 3bcf00829db3..000000000000 Binary files a/test/ipynb/mpl/graph/references/histogram.png and /dev/null differ diff --git a/test/ipynb/mpl/graph/references/histogram_2_sets_with_rest.png b/test/ipynb/mpl/graph/references/histogram_2_sets_with_rest.png deleted file mode 100644 index d72e46de5429..000000000000 Binary files a/test/ipynb/mpl/graph/references/histogram_2_sets_with_rest.png and /dev/null differ diff --git a/test/ipynb/mpl/graph/references/histogram_color.png b/test/ipynb/mpl/graph/references/histogram_color.png deleted file mode 100644 index 81084db6fca2..000000000000 Binary files a/test/ipynb/mpl/graph/references/histogram_color.png and /dev/null differ diff --git a/test/ipynb/mpl/graph/references/histogram_desc_value_sort.png b/test/ipynb/mpl/graph/references/histogram_desc_value_sort.png deleted file mode 100644 index 488e23955129..000000000000 Binary files a/test/ipynb/mpl/graph/references/histogram_desc_value_sort.png and /dev/null differ diff --git a/test/ipynb/mpl/graph/references/histogram_hamming.png b/test/ipynb/mpl/graph/references/histogram_hamming.png deleted file mode 100644 index 7f98be4758d4..000000000000 Binary files a/test/ipynb/mpl/graph/references/histogram_hamming.png and /dev/null differ diff --git a/test/ipynb/mpl/graph/references/histogram_legend.png b/test/ipynb/mpl/graph/references/histogram_legend.png deleted file mode 100644 index 763b387d05c6..000000000000 Binary files a/test/ipynb/mpl/graph/references/histogram_legend.png and /dev/null differ diff --git a/test/ipynb/mpl/graph/references/histogram_multiple_colors.png b/test/ipynb/mpl/graph/references/histogram_multiple_colors.png deleted file mode 100644 index 25a40b324dc6..000000000000 Binary files a/test/ipynb/mpl/graph/references/histogram_multiple_colors.png and /dev/null differ diff --git a/test/ipynb/mpl/graph/references/histogram_title.png b/test/ipynb/mpl/graph/references/histogram_title.png deleted file mode 100644 index d46ec549b05f..000000000000 Binary files a/test/ipynb/mpl/graph/references/histogram_title.png and /dev/null differ diff --git a/test/ipynb/mpl/graph/references/histogram_value_sort.png b/test/ipynb/mpl/graph/references/histogram_value_sort.png deleted file mode 100644 index fde6e9348bbe..000000000000 Binary files a/test/ipynb/mpl/graph/references/histogram_value_sort.png and /dev/null differ diff --git a/test/ipynb/mpl/graph/references/histogram_with_rest.png b/test/ipynb/mpl/graph/references/histogram_with_rest.png deleted file mode 100644 index d91d5f107242..000000000000 Binary files a/test/ipynb/mpl/graph/references/histogram_with_rest.png and /dev/null differ diff --git a/test/ipynb/mpl/graph/references/line_color.png b/test/ipynb/mpl/graph/references/line_color.png deleted file mode 100644 index 78e8b230e34e..000000000000 Binary files a/test/ipynb/mpl/graph/references/line_color.png and /dev/null differ diff --git a/test/ipynb/mpl/graph/references/paulivec.png b/test/ipynb/mpl/graph/references/paulivec.png deleted file mode 100644 index ef78aff4b41a..000000000000 Binary files a/test/ipynb/mpl/graph/references/paulivec.png and /dev/null differ diff --git a/test/ipynb/mpl/graph/references/qsphere.png b/test/ipynb/mpl/graph/references/qsphere.png deleted file mode 100644 index 31e42c438fc7..000000000000 Binary files a/test/ipynb/mpl/graph/references/qsphere.png and /dev/null differ diff --git a/test/ipynb/mpl/graph/references/qubit_color.png b/test/ipynb/mpl/graph/references/qubit_color.png deleted file mode 100644 index cd6f38b179e0..000000000000 Binary files a/test/ipynb/mpl/graph/references/qubit_color.png and /dev/null differ diff --git a/test/ipynb/mpl/graph/references/qubit_labels.png b/test/ipynb/mpl/graph/references/qubit_labels.png deleted file mode 100644 index 0ef0365e1a2f..000000000000 Binary files a/test/ipynb/mpl/graph/references/qubit_labels.png and /dev/null differ diff --git a/test/ipynb/mpl/graph/references/qubit_size.png b/test/ipynb/mpl/graph/references/qubit_size.png deleted file mode 100644 index 49f25e9c8703..000000000000 Binary files a/test/ipynb/mpl/graph/references/qubit_size.png and /dev/null differ diff --git a/test/ipynb/mpl/graph/references/state_city.png b/test/ipynb/mpl/graph/references/state_city.png deleted file mode 100644 index c967bab00216..000000000000 Binary files a/test/ipynb/mpl/graph/references/state_city.png and /dev/null differ diff --git a/test/ipynb/mpl/graph/test_graph_matplotlib_drawer.py b/test/ipynb/mpl/graph/test_graph_matplotlib_drawer.py deleted file mode 100644 index 962c905ffd7b..000000000000 --- a/test/ipynb/mpl/graph/test_graph_matplotlib_drawer.py +++ /dev/null @@ -1,400 +0,0 @@ -# This code is part of Qiskit. -# -# (C) Copyright IBM 2020. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -"""Tests for graph MPL drawer""" - -import unittest - -import json -import os -from contextlib import contextmanager - -from qiskit import BasicAer, execute -from qiskit.test import QiskitTestCase -from qiskit import QuantumCircuit -from qiskit.utils import optionals -from qiskit.visualization.state_visualization import state_drawer -from qiskit.visualization.counts_visualization import plot_histogram -from qiskit.visualization.gate_map import plot_gate_map, plot_coupling_map -from qiskit.providers.fake_provider import ( - FakeArmonk, - FakeBelem, - FakeCasablanca, - FakeRueschlikon, - FakeMumbai, - FakeManhattan, -) - -if optionals.HAS_MATPLOTLIB: - from matplotlib.pyplot import close as mpl_close -else: - raise ImportError('Must have Matplotlib installed. To install, run "pip install matplotlib".') - - -RESULTDIR = os.path.dirname(os.path.abspath(__file__)) - - -@contextmanager -def cwd(path): - """A context manager to run in a particular path""" - oldpwd = os.getcwd() - os.chdir(path) - try: - yield - finally: - os.chdir(oldpwd) - - -class TestGraphMatplotlibDrawer(QiskitTestCase): - """Graph MPL visualization""" - - def setUp(self): - super().setUp() - self.graph_state_drawer = TestGraphMatplotlibDrawer.save_data_wrap(state_drawer, str(self)) - self.graph_count_drawer = TestGraphMatplotlibDrawer.save_data_wrap( - plot_histogram, str(self) - ) - self.graph_plot_gate_map = TestGraphMatplotlibDrawer.save_data_wrap( - plot_gate_map, str(self) - ) - self.graph_plot_coupling_map = TestGraphMatplotlibDrawer.save_data_wrap( - plot_coupling_map, str(self) - ) - - def tearDown(self): - super().tearDown() - mpl_close("all") - - @staticmethod - def save_data_wrap(func, testname): - """A wrapper to save the data a test""" - - def wrapper(*args, **kwargs): - image_filename = kwargs["filename"] - with cwd(RESULTDIR): - results = func(*args, **kwargs) - TestGraphMatplotlibDrawer.save_data(image_filename, testname) - return results - - return wrapper - - @staticmethod - def save_data(image_filename, testname): - """Saves result data of a test""" - datafilename = "result_test.json" - if os.path.exists(datafilename): - with open(datafilename, encoding="UTF-8") as datafile: - data = json.load(datafile) - else: - data = {} - data[image_filename] = {"testname": testname} - with open(datafilename, "w", encoding="UTF-8") as datafile: - json.dump(data, datafile) - - def test_plot_bloch_multivector(self): - """test bloch sphere - See https://github.com/Qiskit/qiskit-terra/issues/6397. - """ - circuit = QuantumCircuit(1) - circuit.h(0) - - # 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", filename="bloch_multivector.png") - - def test_plot_state_hinton(self): - """test plot_state_hinton""" - circuit = QuantumCircuit(1) - circuit.x(0) - - # 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="hinton", filename="hinton.png") - - def test_plot_state_qsphere(self): - """test for plot_state_qsphere""" - circuit = QuantumCircuit(1) - circuit.x(0) - - # 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="qsphere", filename="qsphere.png") - - def test_plot_state_city(self): - """test for plot_state_city""" - circuit = QuantumCircuit(1) - circuit.x(0) - - # 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="city", filename="state_city.png") - - def test_plot_state_paulivec(self): - """test for plot_state_paulivec""" - circuit = QuantumCircuit(1) - circuit.x(0) - - # 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="paulivec", filename="paulivec.png") - - def test_plot_histogram(self): - """for testing the plot_histogram""" - # specifing counts because we do not want oscillation of - # result until a changes is made to plot_histogram - - counts = {"11": 500, "00": 500} - - self.graph_count_drawer(counts, filename="histogram.png") - - def test_plot_histogram_with_rest(self): - """test plot_histogram with 2 datasets and number_to_keep""" - data = [{"00": 3, "01": 5, "10": 6, "11": 12}] - self.graph_count_drawer(data, number_to_keep=2, filename="histogram_with_rest.png") - - def test_plot_histogram_2_sets_with_rest(self): - """test plot_histogram with 2 datasets and number_to_keep""" - data = [ - {"00": 3, "01": 5, "10": 6, "11": 12}, - {"00": 5, "01": 7, "10": 6, "11": 12}, - ] - self.graph_count_drawer(data, number_to_keep=2, filename="histogram_2_sets_with_rest.png") - - def test_plot_histogram_color(self): - """Test histogram with single color""" - - counts = {"00": 500, "11": 500} - - self.graph_count_drawer(data=counts, color="#204940", filename="histogram_color.png") - - def test_plot_histogram_multiple_colors(self): - """Test histogram with multiple custom colors""" - - counts = [ - {"00": 10, "01": 15, "10": 20, "11": 25}, - {"00": 25, "01": 20, "10": 15, "11": 10}, - ] - - self.graph_count_drawer( - data=counts, - color=["#204940", "#c26219"], - filename="histogram_multiple_colors.png", - ) - - def test_plot_histogram_hamming(self): - """Test histogram with hamming distance""" - - counts = {"101": 500, "010": 500, "001": 500, "100": 500} - - self.graph_count_drawer( - data=counts, sort="hamming", target_string="101", filename="histogram_hamming.png" - ) - - def test_plot_histogram_value_sort(self): - """Test histogram with sorting by value""" - - counts = {"101": 300, "010": 240, "001": 80, "100": 150, "110": 160, "000": 280, "111": 60} - - self.graph_count_drawer( - data=counts, sort="value", target_string="000", filename="histogram_value_sort.png" - ) - - def test_plot_histogram_desc_value_sort(self): - """Test histogram with sorting by descending value""" - - counts = {"101": 150, "010": 50, "001": 180, "100": 10, "110": 190, "000": 80, "111": 260} - - self.graph_count_drawer( - data=counts, - sort="value_desc", - target_string="000", - filename="histogram_desc_value_sort.png", - ) - - def test_plot_histogram_legend(self): - """Test histogram with legend""" - - counts = [{"0": 50, "1": 30}, {"0": 30, "1": 40}] - - self.graph_count_drawer( - data=counts, - legend=["first", "second"], - filename="histogram_legend.png", - figsize=(15, 5), - ) - - def test_plot_histogram_title(self): - """Test histogram with title""" - - counts = [{"0": 50, "1": 30}, {"0": 30, "1": 40}] - - self.graph_count_drawer(data=counts, title="My Histogram", filename="histogram_title.png") - - def test_plot_1_qubit_gate_map(self): - """Test plot_gate_map using 1 qubit backend""" - # getting the mock backend from FakeProvider - - backend = FakeArmonk() - - self.graph_plot_gate_map(backend=backend, filename="1_qubit_gate_map.png") - - def test_plot_5_qubit_gate_map(self): - """Test plot_gate_map using 5 qubit backend""" - # getting the mock backend from FakeProvider - - backend = FakeBelem() - - self.graph_plot_gate_map(backend=backend, filename="5_qubit_gate_map.png") - - def test_plot_7_qubit_gate_map(self): - """Test plot_gate_map using 7 qubit backend""" - # getting the mock backend from FakeProvider - - backend = FakeCasablanca() - - self.graph_plot_gate_map(backend=backend, filename="7_qubit_gate_map.png") - - def test_plot_16_qubit_gate_map(self): - """Test plot_gate_map using 16 qubit backend""" - # getting the mock backend from FakeProvider - - backend = FakeRueschlikon() - - self.graph_plot_gate_map(backend=backend, filename="16_qubit_gate_map.png") - - def test_plot_27_qubit_gate_map(self): - """Test plot_gate_map using 27 qubit backend""" - # getting the mock backend from FakeProvider - - backend = FakeMumbai() - - self.graph_plot_gate_map(backend=backend, filename="27_qubit_gate_map.png") - - def test_plot_65_qubit_gate_map(self): - """test for plot_gate_map using 65 qubit backend""" - # getting the mock backend from FakeProvider - - backend = FakeManhattan() - - self.graph_plot_gate_map(backend=backend, filename="65_qubit_gate_map.png") - - def test_figsize(self): - """Test figsize parameter of plot_gate_map""" - # getting the mock backend from FakeProvider - - backend = FakeBelem() - - self.graph_plot_gate_map(backend=backend, figsize=(10, 10), filename="figsize.png") - - def test_qubit_size(self): - """Test qubit_size parameter of plot_gate_map""" - # getting the mock backend from FakeProvider - - backend = FakeBelem() - - self.graph_plot_gate_map(backend=backend, qubit_size=38, filename="qubit_size.png") - - def test_qubit_color(self): - """Test qubit_color parameter of plot_gate_map""" - # getting the mock backend from FakeProvider - - backend = FakeCasablanca() - - self.graph_plot_gate_map( - backend=backend, qubit_color=["#ff0000"] * 7, filename="qubit_color.png" - ) - - def test_qubit_labels(self): - """Test qubit_labels parameter of plot_gate_map""" - # getting the mock backend from FakeProvider - - backend = FakeCasablanca() - - self.graph_plot_gate_map( - backend=backend, qubit_labels=list(range(10, 17, 1)), filename="qubit_labels.png" - ) - - def test_line_color(self): - """Test line_color parameter of plot_gate_map""" - # getting the mock backend from FakeProvider - - backend = FakeManhattan() - - self.graph_plot_gate_map( - backend=backend, line_color=["#00ff00"] * 144, filename="line_color.png" - ) - - def test_font_color(self): - """Test font_color parameter of plot_gate_map""" - # getting the mock backend from FakeProvider - - backend = FakeManhattan() - - self.graph_plot_gate_map(backend=backend, font_color="#ff00ff", filename="font_color.png") - - def test_plot_coupling_map(self): - """Test plot_coupling_map""" - - num_qubits = 5 - qubit_coordinates = [[1, 0], [0, 1], [1, 1], [1, 2], [2, 1]] - coupling_map = [[1, 0], [1, 2], [1, 3], [3, 4]] - - self.graph_plot_coupling_map( - num_qubits=num_qubits, - qubit_coordinates=qubit_coordinates, - coupling_map=coupling_map, - 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) diff --git a/test/visual/__init__.py b/test/visual/__init__.py new file mode 100644 index 000000000000..e9bb25dad5b1 --- /dev/null +++ b/test/visual/__init__.py @@ -0,0 +1,115 @@ +# This code is part of Qiskit. +# +# (C) Copyright IBM 2020. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. + +"""Image comparison tests.""" + +import json +import os +from contextlib import contextmanager +from pathlib import Path + +from PIL import Image, ImageChops, ImageDraw + + +@contextmanager +def cwd(path): + """A context manager to run in a particular path""" + oldpwd = os.getcwd() + os.chdir(path) + try: + yield + finally: + os.chdir(oldpwd) + + +class VisualTestUtilities: + """Utility methods for circuit and graph visual testing""" + + @staticmethod + def _new_gray(size, color): + img = Image.new("L", size) + drawing = ImageDraw.Draw(img) + drawing.rectangle((0, 0) + size, color) + return img + + @staticmethod + def _black_or_b(diff_image, image, reference, opacity=0.85): + """Copied from https://stackoverflow.com/a/30307875""" + thresholded_diff = diff_image + for _ in range(3): + thresholded_diff = ImageChops.add(thresholded_diff, thresholded_diff) + size = diff_image.size + mask = VisualTestUtilities._new_gray(size, int(255 * (opacity))) + shade = VisualTestUtilities._new_gray(size, 0) + new = reference.copy() + new.paste(shade, mask=mask) + if image.size != new.size: + image = image.resize(new.size) + if image.size != thresholded_diff.size: + thresholded_diff = thresholded_diff.resize(image.size) + new.paste(image, mask=thresholded_diff) + return new + + @staticmethod + def _get_black_pixels(image): + black_and_white_version = image.convert("1") + black_pixels = black_and_white_version.histogram()[0] + return black_pixels + + @staticmethod + def _save_diff(current, expected, image_name, failure_diff_dir, failure_prefix): + diff_name = current.split(".") + diff_name.insert(-1, "diff") + diff_name = ".".join(diff_name) + + current = Image.open(current) + expected = Image.open(expected) + + diff = ImageChops.difference(expected, current).convert("L") + + black_pixels = VisualTestUtilities._get_black_pixels(diff) + total_pixels = diff.size[0] * diff.size[1] + diff_ratio = black_pixels / total_pixels + + if diff_ratio != 1: + VisualTestUtilities._black_or_b(diff, current, expected).save( + str(Path(failure_diff_dir) / (failure_prefix + image_name)), "PNG" + ) + else: + VisualTestUtilities._black_or_b(diff, current, expected).save(diff_name, "PNG") + return diff_ratio + + @staticmethod + def save_data_wrap(func, testname, result_dir): + """A wrapper to save the data a test""" + + def wrapper(*args, **kwargs): + image_filename = kwargs["filename"] + with cwd(result_dir): + results = func(*args, **kwargs) + VisualTestUtilities.save_data(image_filename, testname) + return results + + return wrapper + + @staticmethod + def save_data(image_filename, testname): + """Saves result data of a test""" + datafilename = "result_test.json" + if os.path.exists(datafilename): + with open(datafilename, encoding="UTF-8") as datafile: + data = json.load(datafile) + else: + data = {} + data[image_filename] = {"testname": testname} + with open(datafilename, "w", encoding="UTF-8") as datafile: + json.dump(data, datafile) diff --git a/test/ipynb/__init__.py b/test/visual/mpl/__init__.py similarity index 73% rename from test/ipynb/__init__.py rename to test/visual/mpl/__init__.py index c44c4f99c5d6..a62c3b834150 100644 --- a/test/ipynb/__init__.py +++ b/test/visual/mpl/__init__.py @@ -10,6 +10,4 @@ # copyright notice, and modified files need to carry a notice indicating # that they have been altered from the originals. -"""Image comparison tests. You can generate the image references with Binder -in https://mybinder.org/v2/gh///?urlpath=apps/test/ipynb/.ipynb -""" +"""Image comparison test for MPL graph drawer.""" diff --git a/test/ipynb/mpl/__init__.py b/test/visual/mpl/circuit/__init__.py similarity index 71% rename from test/ipynb/mpl/__init__.py rename to test/visual/mpl/circuit/__init__.py index f9d8a5f9d8ef..6a164bf66cad 100644 --- a/test/ipynb/mpl/__init__.py +++ b/test/visual/mpl/circuit/__init__.py @@ -10,7 +10,4 @@ # copyright notice, and modified files need to carry a notice indicating # that they have been altered from the originals. -"""Image comparison test for MPL graph drawer. -You can generate the image references with Binder -in https://mybinder.org/v2/gh///?urlpath=apps/test/ipynb/mpl_tester.ipynb -""" +"""Image comparison test for MPL circuit drawer.""" diff --git a/test/visual/mpl/circuit/references/6095.png b/test/visual/mpl/circuit/references/6095.png new file mode 100644 index 000000000000..47887c7e71b2 Binary files /dev/null and b/test/visual/mpl/circuit/references/6095.png differ diff --git a/test/visual/mpl/circuit/references/barrier_label.png b/test/visual/mpl/circuit/references/barrier_label.png new file mode 100644 index 000000000000..597b38525e25 Binary files /dev/null and b/test/visual/mpl/circuit/references/barrier_label.png differ diff --git a/test/visual/mpl/circuit/references/big_gates.png b/test/visual/mpl/circuit/references/big_gates.png new file mode 100644 index 000000000000..8d5e62eafeec Binary files /dev/null and b/test/visual/mpl/circuit/references/big_gates.png differ diff --git a/test/visual/mpl/circuit/references/bit_conditional_bundle.png b/test/visual/mpl/circuit/references/bit_conditional_bundle.png new file mode 100644 index 000000000000..b2058db95425 Binary files /dev/null and b/test/visual/mpl/circuit/references/bit_conditional_bundle.png differ diff --git a/test/visual/mpl/circuit/references/bit_conditional_no_bundle.png b/test/visual/mpl/circuit/references/bit_conditional_no_bundle.png new file mode 100644 index 000000000000..7f8365892886 Binary files /dev/null and b/test/visual/mpl/circuit/references/bit_conditional_no_bundle.png differ diff --git a/test/visual/mpl/circuit/references/bw.png b/test/visual/mpl/circuit/references/bw.png new file mode 100644 index 000000000000..510baf1add6f Binary files /dev/null and b/test/visual/mpl/circuit/references/bw.png differ diff --git a/test/visual/mpl/circuit/references/calibrations.png b/test/visual/mpl/circuit/references/calibrations.png new file mode 100644 index 000000000000..806f7a7654d7 Binary files /dev/null and b/test/visual/mpl/circuit/references/calibrations.png differ diff --git a/test/visual/mpl/circuit/references/calibrations_with_control_gates.png b/test/visual/mpl/circuit/references/calibrations_with_control_gates.png new file mode 100644 index 000000000000..10abf1044344 Binary files /dev/null and b/test/visual/mpl/circuit/references/calibrations_with_control_gates.png differ diff --git a/test/visual/mpl/circuit/references/calibrations_with_rzz_and_rxx.png b/test/visual/mpl/circuit/references/calibrations_with_rzz_and_rxx.png new file mode 100644 index 000000000000..2e1c621dd646 Binary files /dev/null and b/test/visual/mpl/circuit/references/calibrations_with_rzz_and_rxx.png differ diff --git a/test/visual/mpl/circuit/references/calibrations_with_swap_and_reset.png b/test/visual/mpl/circuit/references/calibrations_with_swap_and_reset.png new file mode 100644 index 000000000000..174663c4b866 Binary files /dev/null and b/test/visual/mpl/circuit/references/calibrations_with_swap_and_reset.png differ diff --git a/test/visual/mpl/circuit/references/cnot.png b/test/visual/mpl/circuit/references/cnot.png new file mode 100644 index 000000000000..4d3815fc535b Binary files /dev/null and b/test/visual/mpl/circuit/references/cnot.png differ diff --git a/test/visual/mpl/circuit/references/cond_bits_reverse.png b/test/visual/mpl/circuit/references/cond_bits_reverse.png new file mode 100644 index 000000000000..b5fcc646707d Binary files /dev/null and b/test/visual/mpl/circuit/references/cond_bits_reverse.png differ diff --git a/test/visual/mpl/circuit/references/creg_initial_false.png b/test/visual/mpl/circuit/references/creg_initial_false.png new file mode 100644 index 000000000000..dd5fa0762f53 Binary files /dev/null and b/test/visual/mpl/circuit/references/creg_initial_false.png differ diff --git a/test/visual/mpl/circuit/references/creg_initial_true.png b/test/visual/mpl/circuit/references/creg_initial_true.png new file mode 100644 index 000000000000..0972c9af28a4 Binary files /dev/null and b/test/visual/mpl/circuit/references/creg_initial_true.png differ diff --git a/test/visual/mpl/circuit/references/cswap_rzz.png b/test/visual/mpl/circuit/references/cswap_rzz.png new file mode 100644 index 000000000000..5b4aa82138bc Binary files /dev/null and b/test/visual/mpl/circuit/references/cswap_rzz.png differ diff --git a/test/visual/mpl/circuit/references/ctrl_labels.png b/test/visual/mpl/circuit/references/ctrl_labels.png new file mode 100644 index 000000000000..ff4106a8b207 Binary files /dev/null and b/test/visual/mpl/circuit/references/ctrl_labels.png differ diff --git a/test/visual/mpl/circuit/references/cz.png b/test/visual/mpl/circuit/references/cz.png new file mode 100644 index 000000000000..5ef4250831e6 Binary files /dev/null and b/test/visual/mpl/circuit/references/cz.png differ diff --git a/test/visual/mpl/circuit/references/empty_circut.png b/test/visual/mpl/circuit/references/empty_circut.png new file mode 100644 index 000000000000..f3714b09d2cb Binary files /dev/null and b/test/visual/mpl/circuit/references/empty_circut.png differ diff --git a/test/visual/mpl/circuit/references/figwidth.png b/test/visual/mpl/circuit/references/figwidth.png new file mode 100644 index 000000000000..80a645be41cf Binary files /dev/null and b/test/visual/mpl/circuit/references/figwidth.png differ diff --git a/test/visual/mpl/circuit/references/fold_4.png b/test/visual/mpl/circuit/references/fold_4.png new file mode 100644 index 000000000000..460c7d0da5b2 Binary files /dev/null and b/test/visual/mpl/circuit/references/fold_4.png differ diff --git a/test/visual/mpl/circuit/references/fold_minus1.png b/test/visual/mpl/circuit/references/fold_minus1.png new file mode 100644 index 000000000000..784ed2fb2f3f Binary files /dev/null and b/test/visual/mpl/circuit/references/fold_minus1.png differ diff --git a/test/visual/mpl/circuit/references/fold_with_conditions.png b/test/visual/mpl/circuit/references/fold_with_conditions.png new file mode 100644 index 000000000000..7576e07b4c15 Binary files /dev/null and b/test/visual/mpl/circuit/references/fold_with_conditions.png differ diff --git a/test/visual/mpl/circuit/references/ghz_to_gate.png b/test/visual/mpl/circuit/references/ghz_to_gate.png new file mode 100644 index 000000000000..ed01451db05b Binary files /dev/null and b/test/visual/mpl/circuit/references/ghz_to_gate.png differ diff --git a/test/visual/mpl/circuit/references/global_phase.png b/test/visual/mpl/circuit/references/global_phase.png new file mode 100644 index 000000000000..d90ab8ff3128 Binary files /dev/null and b/test/visual/mpl/circuit/references/global_phase.png differ diff --git a/test/visual/mpl/circuit/references/idle_wires_barrier.png b/test/visual/mpl/circuit/references/idle_wires_barrier.png new file mode 100644 index 000000000000..ba196bff7c5e Binary files /dev/null and b/test/visual/mpl/circuit/references/idle_wires_barrier.png differ diff --git a/test/visual/mpl/circuit/references/init_reset.png b/test/visual/mpl/circuit/references/init_reset.png new file mode 100644 index 000000000000..6413b6a0e57e Binary files /dev/null and b/test/visual/mpl/circuit/references/init_reset.png differ diff --git a/test/visual/mpl/circuit/references/instruction_1q_1c.png b/test/visual/mpl/circuit/references/instruction_1q_1c.png new file mode 100644 index 000000000000..46557c81002c Binary files /dev/null and b/test/visual/mpl/circuit/references/instruction_1q_1c.png differ diff --git a/test/visual/mpl/circuit/references/instruction_3q_3c_circ1.png b/test/visual/mpl/circuit/references/instruction_3q_3c_circ1.png new file mode 100644 index 000000000000..6558b8b23388 Binary files /dev/null and b/test/visual/mpl/circuit/references/instruction_3q_3c_circ1.png differ diff --git a/test/visual/mpl/circuit/references/instruction_3q_3c_circ2.png b/test/visual/mpl/circuit/references/instruction_3q_3c_circ2.png new file mode 100644 index 000000000000..b4cf4ffe71a7 Binary files /dev/null and b/test/visual/mpl/circuit/references/instruction_3q_3c_circ2.png differ diff --git a/test/visual/mpl/circuit/references/instruction_3q_3c_circ3.png b/test/visual/mpl/circuit/references/instruction_3q_3c_circ3.png new file mode 100644 index 000000000000..b1bf5a4a2b94 Binary files /dev/null and b/test/visual/mpl/circuit/references/instruction_3q_3c_circ3.png differ diff --git a/test/visual/mpl/circuit/references/iqx-dark_color.png b/test/visual/mpl/circuit/references/iqx-dark_color.png new file mode 100644 index 000000000000..2da76c4c9be9 Binary files /dev/null and b/test/visual/mpl/circuit/references/iqx-dark_color.png differ diff --git a/test/visual/mpl/circuit/references/iqx_color.png b/test/visual/mpl/circuit/references/iqx_color.png new file mode 100644 index 000000000000..4e3022bdeb20 Binary files /dev/null and b/test/visual/mpl/circuit/references/iqx_color.png differ diff --git a/test/visual/mpl/circuit/references/long_name.png b/test/visual/mpl/circuit/references/long_name.png new file mode 100644 index 000000000000..59d1f8ae6f13 Binary files /dev/null and b/test/visual/mpl/circuit/references/long_name.png differ diff --git a/test/visual/mpl/circuit/references/meas_condition.png b/test/visual/mpl/circuit/references/meas_condition.png new file mode 100644 index 000000000000..7e1e6c68fb7c Binary files /dev/null and b/test/visual/mpl/circuit/references/meas_condition.png differ diff --git a/test/visual/mpl/circuit/references/measure_cond_bits_false.png b/test/visual/mpl/circuit/references/measure_cond_bits_false.png new file mode 100644 index 000000000000..5d382a4d865f Binary files /dev/null and b/test/visual/mpl/circuit/references/measure_cond_bits_false.png differ diff --git a/test/visual/mpl/circuit/references/measure_cond_bits_right.png b/test/visual/mpl/circuit/references/measure_cond_bits_right.png new file mode 100644 index 000000000000..86b07ac5b850 Binary files /dev/null and b/test/visual/mpl/circuit/references/measure_cond_bits_right.png differ diff --git a/test/visual/mpl/circuit/references/measure_cond_bits_true.png b/test/visual/mpl/circuit/references/measure_cond_bits_true.png new file mode 100644 index 000000000000..902a396bb630 Binary files /dev/null and b/test/visual/mpl/circuit/references/measure_cond_bits_true.png differ diff --git a/test/visual/mpl/circuit/references/measure_cond_false.png b/test/visual/mpl/circuit/references/measure_cond_false.png new file mode 100644 index 000000000000..d49d7e871d20 Binary files /dev/null and b/test/visual/mpl/circuit/references/measure_cond_false.png differ diff --git a/test/visual/mpl/circuit/references/measure_cond_true.png b/test/visual/mpl/circuit/references/measure_cond_true.png new file mode 100644 index 000000000000..a5cd5aa81fc6 Binary files /dev/null and b/test/visual/mpl/circuit/references/measure_cond_true.png differ diff --git a/test/visual/mpl/circuit/references/multi_underscore_false.png b/test/visual/mpl/circuit/references/multi_underscore_false.png new file mode 100644 index 000000000000..1592de5bdeb7 Binary files /dev/null and b/test/visual/mpl/circuit/references/multi_underscore_false.png differ diff --git a/test/visual/mpl/circuit/references/multi_underscore_true.png b/test/visual/mpl/circuit/references/multi_underscore_true.png new file mode 100644 index 000000000000..230d1814af8b Binary files /dev/null and b/test/visual/mpl/circuit/references/multi_underscore_true.png differ diff --git a/test/visual/mpl/circuit/references/no_barriers.png b/test/visual/mpl/circuit/references/no_barriers.png new file mode 100644 index 000000000000..f08939413175 Binary files /dev/null and b/test/visual/mpl/circuit/references/no_barriers.png differ diff --git a/test/visual/mpl/circuit/references/no_op_circut.png b/test/visual/mpl/circuit/references/no_op_circut.png new file mode 100644 index 000000000000..9046ef0d2ee3 Binary files /dev/null and b/test/visual/mpl/circuit/references/no_op_circut.png differ diff --git a/test/visual/mpl/circuit/references/one_bit_regs.png b/test/visual/mpl/circuit/references/one_bit_regs.png new file mode 100644 index 000000000000..7d9f2aa1a626 Binary files /dev/null and b/test/visual/mpl/circuit/references/one_bit_regs.png differ diff --git a/test/visual/mpl/circuit/references/partial_layout.png b/test/visual/mpl/circuit/references/partial_layout.png new file mode 100644 index 000000000000..f1262af68e96 Binary files /dev/null and b/test/visual/mpl/circuit/references/partial_layout.png differ diff --git a/test/visual/mpl/circuit/references/pauli_clifford.png b/test/visual/mpl/circuit/references/pauli_clifford.png new file mode 100644 index 000000000000..55d8a133114b Binary files /dev/null and b/test/visual/mpl/circuit/references/pauli_clifford.png differ diff --git a/test/visual/mpl/circuit/references/pi_in_param_expr.png b/test/visual/mpl/circuit/references/pi_in_param_expr.png new file mode 100644 index 000000000000..ed4b0adf92f8 Binary files /dev/null and b/test/visual/mpl/circuit/references/pi_in_param_expr.png differ diff --git a/test/visual/mpl/circuit/references/plot_barriers_false.png b/test/visual/mpl/circuit/references/plot_barriers_false.png new file mode 100644 index 000000000000..ac7e155f8b08 Binary files /dev/null and b/test/visual/mpl/circuit/references/plot_barriers_false.png differ diff --git a/test/visual/mpl/circuit/references/plot_barriers_true.png b/test/visual/mpl/circuit/references/plot_barriers_true.png new file mode 100644 index 000000000000..2b712d8b1726 Binary files /dev/null and b/test/visual/mpl/circuit/references/plot_barriers_true.png differ diff --git a/test/visual/mpl/circuit/references/plot_partial_barrier.png b/test/visual/mpl/circuit/references/plot_partial_barrier.png new file mode 100644 index 000000000000..307b2d55e67f Binary files /dev/null and b/test/visual/mpl/circuit/references/plot_partial_barrier.png differ diff --git a/test/visual/mpl/circuit/references/r_gates.png b/test/visual/mpl/circuit/references/r_gates.png new file mode 100644 index 000000000000..3b444690ea6d Binary files /dev/null and b/test/visual/mpl/circuit/references/r_gates.png differ diff --git a/test/visual/mpl/circuit/references/reg_conditional.png b/test/visual/mpl/circuit/references/reg_conditional.png new file mode 100644 index 000000000000..c22acdfdd770 Binary files /dev/null and b/test/visual/mpl/circuit/references/reg_conditional.png differ diff --git a/test/visual/mpl/circuit/references/registerless_one_bit.png b/test/visual/mpl/circuit/references/registerless_one_bit.png new file mode 100644 index 000000000000..f0e6609686c5 Binary files /dev/null and b/test/visual/mpl/circuit/references/registerless_one_bit.png differ diff --git a/test/visual/mpl/circuit/references/reverse_bits.png b/test/visual/mpl/circuit/references/reverse_bits.png new file mode 100644 index 000000000000..8957f30b0f6f Binary files /dev/null and b/test/visual/mpl/circuit/references/reverse_bits.png differ diff --git a/test/visual/mpl/circuit/references/reverse_bits_cond_false.png b/test/visual/mpl/circuit/references/reverse_bits_cond_false.png new file mode 100644 index 000000000000..a3c8e458623c Binary files /dev/null and b/test/visual/mpl/circuit/references/reverse_bits_cond_false.png differ diff --git a/test/visual/mpl/circuit/references/reverse_bits_cond_true.png b/test/visual/mpl/circuit/references/reverse_bits_cond_true.png new file mode 100644 index 000000000000..6996256b493e Binary files /dev/null and b/test/visual/mpl/circuit/references/reverse_bits_cond_true.png differ diff --git a/test/visual/mpl/circuit/references/scale_default.png b/test/visual/mpl/circuit/references/scale_default.png new file mode 100644 index 000000000000..1d53f3f97749 Binary files /dev/null and b/test/visual/mpl/circuit/references/scale_default.png differ diff --git a/test/visual/mpl/circuit/references/scale_double.png b/test/visual/mpl/circuit/references/scale_double.png new file mode 100644 index 000000000000..15d603b38a19 Binary files /dev/null and b/test/visual/mpl/circuit/references/scale_double.png differ diff --git a/test/visual/mpl/circuit/references/scale_half.png b/test/visual/mpl/circuit/references/scale_half.png new file mode 100644 index 000000000000..de43ceb70060 Binary files /dev/null and b/test/visual/mpl/circuit/references/scale_half.png differ diff --git a/test/visual/mpl/circuit/references/sidetext_condition.png b/test/visual/mpl/circuit/references/sidetext_condition.png new file mode 100644 index 000000000000..8b9ab8045006 Binary files /dev/null and b/test/visual/mpl/circuit/references/sidetext_condition.png differ diff --git a/test/visual/mpl/circuit/references/style_custom_gates.png b/test/visual/mpl/circuit/references/style_custom_gates.png new file mode 100644 index 000000000000..f059cf37682c Binary files /dev/null and b/test/visual/mpl/circuit/references/style_custom_gates.png differ diff --git a/test/visual/mpl/circuit/references/subfont.png b/test/visual/mpl/circuit/references/subfont.png new file mode 100644 index 000000000000..f231ff145594 Binary files /dev/null and b/test/visual/mpl/circuit/references/subfont.png differ diff --git a/test/visual/mpl/circuit/references/textbook_color.png b/test/visual/mpl/circuit/references/textbook_color.png new file mode 100644 index 000000000000..ae0f96765b1c Binary files /dev/null and b/test/visual/mpl/circuit/references/textbook_color.png differ diff --git a/test/visual/mpl/circuit/references/user_ax.png b/test/visual/mpl/circuit/references/user_ax.png new file mode 100644 index 000000000000..4f08d42c675e Binary files /dev/null and b/test/visual/mpl/circuit/references/user_ax.png differ diff --git a/test/visual/mpl/circuit/references/user_style.png b/test/visual/mpl/circuit/references/user_style.png new file mode 100644 index 000000000000..fe4800525ae2 Binary files /dev/null and b/test/visual/mpl/circuit/references/user_style.png differ diff --git a/test/visual/mpl/circuit/references/wide_params.png b/test/visual/mpl/circuit/references/wide_params.png new file mode 100644 index 000000000000..81f1c41dd065 Binary files /dev/null and b/test/visual/mpl/circuit/references/wide_params.png differ diff --git a/test/visual/mpl/circuit/references/wire_order.png b/test/visual/mpl/circuit/references/wire_order.png new file mode 100644 index 000000000000..4338917f7c02 Binary files /dev/null and b/test/visual/mpl/circuit/references/wire_order.png differ diff --git a/test/ipynb/mpl/circuit/test_circuit_matplotlib_drawer.py b/test/visual/mpl/circuit/test_circuit_matplotlib_drawer.py similarity index 55% rename from test/ipynb/mpl/circuit/test_circuit_matplotlib_drawer.py rename to test/visual/mpl/circuit/test_circuit_matplotlib_drawer.py index 7e3473e35e3a..015685c82b64 100644 --- a/test/ipynb/mpl/circuit/test_circuit_matplotlib_drawer.py +++ b/test/visual/mpl/circuit/test_circuit_matplotlib_drawer.py @@ -14,10 +14,10 @@ import unittest -import json import os -from contextlib import contextmanager import math +from test.visual import VisualTestUtilities +from pathlib import Path import numpy as np from numpy import pi @@ -49,65 +49,55 @@ else: raise ImportError('Must have Matplotlib installed. To install, run "pip install matplotlib".') +BASE_DIR = Path(__file__).parent +RESULT_DIR = Path(BASE_DIR) / "circuit_results" +TEST_REFERENCE_DIR = Path(BASE_DIR) / "references" +FAILURE_DIFF_DIR = Path(BASE_DIR).parent / "visual_test_failures" +FAILURE_PREFIX = "circuit_failure_" -RESULTDIR = os.path.dirname(os.path.abspath(__file__)) - -@contextmanager -def cwd(path): - """A context manager to run in a particular path""" - oldpwd = os.getcwd() - os.chdir(path) - try: - yield - finally: - os.chdir(oldpwd) - - -class TestMatplotlibDrawer(QiskitTestCase): +class TestCircuitMatplotlibDrawer(QiskitTestCase): """Circuit MPL visualization""" def setUp(self): super().setUp() - self.circuit_drawer = TestMatplotlibDrawer.save_data_wrap( - _matplotlib_circuit_drawer, str(self) + self.circuit_drawer = VisualTestUtilities.save_data_wrap( + _matplotlib_circuit_drawer, str(self), RESULT_DIR ) + if not os.path.exists(FAILURE_DIFF_DIR): + os.makedirs(FAILURE_DIFF_DIR) + + if not os.path.exists(RESULT_DIR): + os.makedirs(RESULT_DIR) + def tearDown(self): super().tearDown() mpl_close("all") @staticmethod - def save_data_wrap(func, testname): - """A wrapper to save the data from a test""" - - def wrapper(*args, **kwargs): - image_filename = kwargs["filename"] - with cwd(RESULTDIR): - results = func(*args, **kwargs) - TestMatplotlibDrawer.save_data(image_filename, testname) - return results - - return wrapper + def _image_path(image_name): + return os.path.join(RESULT_DIR, image_name) @staticmethod - def save_data(image_filename, testname): - """Saves result data of a test""" - datafilename = "result_test.json" - if os.path.exists(datafilename): - with open(datafilename) as datafile: - data = json.load(datafile) - else: - data = {} - data[image_filename] = {"testname": testname} - with open(datafilename, "w") as datafile: - json.dump(data, datafile) + def _reference_path(image_name): + return os.path.join(TEST_REFERENCE_DIR, image_name) def test_empty_circuit(self): """Test empty circuit""" circuit = QuantumCircuit() - self.circuit_drawer(circuit, filename="empty_circut.png") + fname = "empty_circut.png" + self.circuit_drawer(circuit, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_calibrations(self): """Test calibrations annotations @@ -126,7 +116,17 @@ def test_calibrations(self): circuit.add_calibration("h", [0], h_q0) - self.circuit_drawer(circuit, filename="calibrations.png") + fname = "calibrations.png" + self.circuit_drawer(circuit, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_calibrations_with_control_gates(self): """Test calibrations annotations @@ -153,7 +153,17 @@ def test_calibrations_with_control_gates(self): circuit.add_calibration("ch", [0, 1], ch_q01) - self.circuit_drawer(circuit, filename="calibrations_with_control_gates.png") + fname = "calibrations_with_control_gates.png" + self.circuit_drawer(circuit, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_calibrations_with_swap_and_reset(self): """Test calibrations annotations @@ -180,7 +190,17 @@ def test_calibrations_with_swap_and_reset(self): circuit.add_calibration("reset", [0], reset_q0) - self.circuit_drawer(circuit, filename="calibrations_with_swap_and_reset.png") + fname = "calibrations_with_swap_and_reset.png" + self.circuit_drawer(circuit, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_calibrations_with_rzz_and_rxx(self): """Test calibrations annotations @@ -206,13 +226,34 @@ def test_calibrations_with_rzz_and_rxx(self): circuit.add_calibration("rxx", [0, 1], rxx_q01) - self.circuit_drawer(circuit, filename="calibrations_with_rzz_and_rxx.png") + fname = "calibrations_with_rzz_and_rxx.png" + self.circuit_drawer(circuit, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_no_ops(self): """Test circuit with no ops. See https://github.com/Qiskit/qiskit-terra/issues/5393""" circuit = QuantumCircuit(2, 3) - self.circuit_drawer(circuit, filename="no_op_circut.png") + + fname = "no_op_circut.png" + self.circuit_drawer(circuit, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_long_name(self): """Test to see that long register names can be seen completely @@ -230,7 +271,17 @@ def test_long_name(self): circuit.h(qr) circuit.h(qr) - self.circuit_drawer(circuit, filename="long_name.png") + fname = "long_name.png" + self.circuit_drawer(circuit, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_multi_underscore_reg_names(self): """Test that multi-underscores in register names display properly""" @@ -240,8 +291,29 @@ def test_multi_underscore_reg_names(self): c_reg3 = ClassicalRegister(3, "c3_re_g__g") circuit = QuantumCircuit(q_reg1, q_reg3, c_reg1, c_reg3) - self.circuit_drawer(circuit, cregbundle=True, filename="multi_underscore_true.png") - self.circuit_drawer(circuit, cregbundle=False, filename="multi_underscore_false.png") + fname = "multi_underscore_true.png" + self.circuit_drawer(circuit, cregbundle=True, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + fname2 = "multi_underscore_false.png" + self.circuit_drawer(circuit, cregbundle=False, filename=fname2) + + ratio2 = VisualTestUtilities._save_diff( + self._image_path(fname2), + self._reference_path(fname2), + fname2, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + + self.assertEqual(ratio, 1) + self.assertEqual(ratio2, 1) def test_conditional(self): """Test that circuits with conditionals draw correctly""" @@ -254,7 +326,17 @@ def test_conditional(self): circuit.measure(qr, cr) circuit.h(qr[0]).c_if(cr, 2) - self.circuit_drawer(circuit, filename="reg_conditional.png") + fname = "reg_conditional.png" + self.circuit_drawer(circuit, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_bit_conditional_with_cregbundle(self): """Test that circuits with single bit conditionals draw correctly @@ -268,7 +350,17 @@ def test_bit_conditional_with_cregbundle(self): circuit.h(qr[0]).c_if(cr[0], 1) circuit.x(qr[1]).c_if(cr[1], 0) - self.circuit_drawer(circuit, filename="bit_conditional_bundle.png") + fname = "bit_conditional_bundle.png" + self.circuit_drawer(circuit, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_bit_conditional_no_cregbundle(self): """Test that circuits with single bit conditionals draw correctly @@ -282,7 +374,17 @@ def test_bit_conditional_no_cregbundle(self): circuit.h(qr[0]).c_if(cr[0], 1) circuit.x(qr[1]).c_if(cr[1], 0) - self.circuit_drawer(circuit, filename="bit_conditional_no_bundle.png", cregbundle=False) + fname = "bit_conditional_no_bundle.png" + self.circuit_drawer(circuit, filename=fname, cregbundle=False) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_plot_partial_barrier(self): """Test plotting of partial barriers.""" @@ -297,7 +399,17 @@ def test_plot_partial_barrier(self): circuit.barrier(0) circuit.h(q[0]) - self.circuit_drawer(circuit, filename="plot_partial_barrier.png", plot_barriers=True) + fname = "plot_partial_barrier.png" + self.circuit_drawer(circuit, filename=fname, plot_barriers=True) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_plot_barriers(self): """Test to see that plotting barriers works. @@ -321,8 +433,29 @@ def test_plot_barriers(self): circuit.snapshot("1") # check the barriers plot properly when plot_barriers= True - self.circuit_drawer(circuit, filename="plot_barriers_true.png", plot_barriers=True) - self.circuit_drawer(circuit, filename="plot_barriers_false.png", plot_barriers=False) + fname = "plot_barriers_true.png" + self.circuit_drawer(circuit, filename=fname, plot_barriers=True) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + fname2 = "plot_barriers_false.png" + self.circuit_drawer(circuit, filename=fname2, plot_barriers=False) + + ratio2 = VisualTestUtilities._save_diff( + self._image_path(fname2), + self._reference_path(fname2), + fname2, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + + self.assertEqual(ratio, 1) + self.assertEqual(ratio2, 1) def test_no_barriers_false(self): """Generate the same circuit as test_plot_barriers but without the barrier commands @@ -333,7 +466,17 @@ def test_no_barriers_false(self): circuit.h(q1[0]) circuit.h(q1[1]) - self.circuit_drawer(circuit, filename="no_barriers.png", plot_barriers=False) + fname = "no_barriers.png" + self.circuit_drawer(circuit, filename=fname, plot_barriers=False) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_fold_minus1(self): """Test to see that fold=-1 is no folding""" @@ -344,7 +487,17 @@ def test_fold_minus1(self): circuit.h(0) circuit.x(0) - self.circuit_drawer(circuit, fold=-1, filename="fold_minus1.png") + fname = "fold_minus1.png" + self.circuit_drawer(circuit, fold=-1, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_fold_4(self): """Test to see that fold=4 is folding""" @@ -355,7 +508,17 @@ def test_fold_4(self): circuit.h(0) circuit.x(0) - self.circuit_drawer(circuit, fold=4, filename="fold_4.png") + fname = "fold_4.png" + self.circuit_drawer(circuit, fold=4, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_big_gates(self): """Test large gates with params""" @@ -382,7 +545,17 @@ def test_big_gates(self): circuit = circuit.bind_parameters({theta: 1}) circuit.isometry(np.eye(4, 4), list(range(3, 5)), []) - self.circuit_drawer(circuit, filename="big_gates.png") + fname = "big_gates.png" + self.circuit_drawer(circuit, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_cnot(self): """Test different cnot gates (ccnot, mcx, etc)""" @@ -395,7 +568,17 @@ def test_cnot(self): circuit.append(MCXGate(num_ctrl_qubits=3, ctrl_state="101"), [qr[0], qr[1], qr[2], qr[4]]) circuit.append(MCXVChain(3, dirty_ancillas=True), [qr[0], qr[1], qr[2], qr[3], qr[5]]) - self.circuit_drawer(circuit, filename="cnot.png") + fname = "cnot.png" + self.circuit_drawer(circuit, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_cz(self): """Test Z and Controlled-Z Gates""" @@ -407,7 +590,17 @@ def test_cz(self): circuit.append(ZGate().control(2), [1, 2, 3]) circuit.append(ZGate().control(1, ctrl_state="0", label="CZ Gate"), [2, 3]) - self.circuit_drawer(circuit, filename="cz.png") + fname = "cz.png" + self.circuit_drawer(circuit, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_pauli_clifford(self): """Test Pauli(green) and Clifford(blue) gates""" @@ -427,7 +620,17 @@ def test_pauli_clifford(self): circuit.iswap(3, 4) circuit.dcx(3, 4) - self.circuit_drawer(circuit, filename="pauli_clifford.png") + fname = "pauli_clifford.png" + self.circuit_drawer(circuit, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_creg_initial(self): """Test cregbundle and initial state options""" @@ -438,13 +641,30 @@ def test_creg_initial(self): circuit.h(0) circuit.x(1) - self.circuit_drawer( - circuit, filename="creg_initial_true.png", cregbundle=True, initial_state=True + fname = "creg_initial_true.png" + self.circuit_drawer(circuit, filename=fname, cregbundle=True, initial_state=True) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, ) - self.circuit_drawer( - circuit, filename="creg_initial_false.png", cregbundle=False, initial_state=False + fname2 = "creg_initial_false.png" + self.circuit_drawer(circuit, filename=fname2, cregbundle=False, initial_state=False) + + ratio2 = VisualTestUtilities._save_diff( + self._image_path(fname2), + self._reference_path(fname2), + fname2, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, ) + self.assertEqual(ratio, 1) + self.assertEqual(ratio2, 1) + def test_r_gates(self): """Test all R gates""" qr = QuantumRegister(4, "q") @@ -458,7 +678,17 @@ def test_r_gates(self): circuit.rzx(-pi / 2, 0, 1) circuit.rzz(pi / 2, 2, 3) - self.circuit_drawer(circuit, filename="r_gates.png") + fname = "r_gates.png" + self.circuit_drawer(circuit, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_ctrl_labels(self): """Test control labels""" @@ -472,7 +702,17 @@ def test_ctrl_labels(self): [qr[1], qr[2], qr[3], qr[0]], ) - self.circuit_drawer(circuit, filename="ctrl_labels.png") + fname = "ctrl_labels.png" + self.circuit_drawer(circuit, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_cswap_rzz(self): """Test controlled swap and rzz gates""" @@ -481,7 +721,17 @@ def test_cswap_rzz(self): circuit.cswap(0, 1, 2) circuit.append(RZZGate(3 * pi / 4).control(3, ctrl_state="010"), [2, 1, 4, 3, 0]) - self.circuit_drawer(circuit, filename="cswap_rzz.png") + fname = "cswap_rzz.png" + self.circuit_drawer(circuit, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_ghz_to_gate(self): """Test controlled GHZ to_gate circuit""" @@ -495,7 +745,17 @@ def test_ghz_to_gate(self): ccghz = ghz.control(2, ctrl_state="10") circuit.append(ccghz, [4, 0, 1, 3, 2]) - self.circuit_drawer(circuit, filename="ghz_to_gate.png") + fname = "ghz_to_gate.png" + self.circuit_drawer(circuit, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_scale(self): """Tests scale @@ -503,9 +763,41 @@ def test_scale(self): circuit = QuantumCircuit(5) circuit.unitary(random_unitary(2**5), circuit.qubits) - self.circuit_drawer(circuit, filename="scale_default.png") - self.circuit_drawer(circuit, filename="scale_half.png", scale=0.5) - self.circuit_drawer(circuit, filename="scale_double.png", scale=2) + fname = "scale_default.png" + self.circuit_drawer(circuit, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + fname2 = "scale_half.png" + self.circuit_drawer(circuit, filename=fname2, scale=0.5) + + ratio2 = VisualTestUtilities._save_diff( + self._image_path(fname2), + self._reference_path(fname2), + fname2, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + + fname3 = "scale_double.png" + self.circuit_drawer(circuit, filename=fname3, scale=2) + + ratio3 = VisualTestUtilities._save_diff( + self._image_path(fname3), + self._reference_path(fname3), + fname3, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + + self.assertEqual(ratio, 1) + self.assertEqual(ratio2, 1) + self.assertEqual(ratio3, 1) def test_pi_param_expr(self): """Test pi in circuit with parameter expression.""" @@ -513,7 +805,17 @@ def test_pi_param_expr(self): circuit = QuantumCircuit(1) circuit.rx((pi - x) * (pi - y), 0) - self.circuit_drawer(circuit, filename="pi_in_param_expr.png") + fname = "pi_in_param_expr.png" + self.circuit_drawer(circuit, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_partial_layout(self): """Tests partial_layout @@ -529,7 +831,17 @@ def test_partial_layout(self): seed_transpiler=0, ) - self.circuit_drawer(transpiled, filename="partial_layout.png") + fname = "partial_layout.png" + self.circuit_drawer(transpiled, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_init_reset(self): """Test reset and initialize with 1 and 2 qubits""" @@ -538,17 +850,38 @@ def test_init_reset(self): circuit.reset(1) circuit.initialize([0, 1, 0, 0], [0, 1]) - self.circuit_drawer(circuit, filename="init_reset.png") + fname = "init_reset.png" + self.circuit_drawer(circuit, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_with_global_phase(self): """Tests with global phase""" circuit = QuantumCircuit(3, global_phase=1.57079632679) circuit.h(range(3)) - self.circuit_drawer(circuit, filename="global_phase.png") + fname = "global_phase.png" + self.circuit_drawer(circuit, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_alternative_colors(self): """Tests alternative color schemes""" + ratios = [] for style in ["iqx", "iqx-dark", "textbook"]: with self.subTest(style=style): circuit = QuantumCircuit(7) @@ -577,7 +910,20 @@ def test_alternative_colors(self): circuit.barrier(5, 6) circuit.reset(5) - self.circuit_drawer(circuit, style={"name": style}, filename=f"{style}_color.png") + fname = f"{style}_color.png" + self.circuit_drawer(circuit, style={"name": style}, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + ratios.append(ratio) + + for ratio in ratios: + self.assertEqual(ratio, 1) def test_reverse_bits(self): """Tests reverse_bits parameter""" @@ -586,7 +932,17 @@ def test_reverse_bits(self): circuit.cx(0, 1) circuit.ccx(2, 1, 0) - self.circuit_drawer(circuit, reverse_bits=True, filename="reverse_bits.png") + fname = "reverse_bits.png" + self.circuit_drawer(circuit, reverse_bits=True, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_bw(self): """Tests black and white style parameter""" @@ -599,7 +955,17 @@ def test_bw(self): circuit.swap(1, 2) circuit.measure_all() - self.circuit_drawer(circuit, style={"name": "bw"}, filename="bw.png") + fname = "bw.png" + self.circuit_drawer(circuit, style={"name": "bw"}, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_user_style(self): """Tests loading a user style""" @@ -630,6 +996,7 @@ def test_user_style(self): circuit.barrier(5, 6) circuit.reset(5) + fname = "user_style.png" self.circuit_drawer( circuit, style={ @@ -637,9 +1004,18 @@ def test_user_style(self): "displaytext": {"H2": "H_2"}, "displaycolor": {"H2": ("#EEDD00", "#FF0000")}, }, - filename="user_style.png", + filename=fname, ) + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) + def test_subfont_change(self): """Tests changing the subfont size""" circuit = QuantumCircuit(3) @@ -649,9 +1025,19 @@ def test_subfont_change(self): circuit.p(pi / 2, 2) style = {"name": "iqx", "subfontsize": 11} - self.circuit_drawer(circuit, style=style, filename="subfont.png") + fname = "subfont.png" + self.circuit_drawer(circuit, style=style, filename=fname) self.assertEqual(style, {"name": "iqx", "subfontsize": 11}) # check does not change style + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) + def test_meas_condition(self): """Tests measure with a condition""" qr = QuantumRegister(2, "qr") @@ -660,7 +1046,18 @@ def test_meas_condition(self): circuit.h(qr[0]) circuit.measure(qr[0], cr[0]) circuit.h(qr[1]).c_if(cr, 1) - self.circuit_drawer(circuit, filename="meas_condition.png") + + fname = "meas_condition.png" + self.circuit_drawer(circuit, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_reverse_bits_condition(self): """Tests reverse_bits with a condition and gate above""" @@ -675,13 +1072,31 @@ def test_reverse_bits_condition(self): circuit.x(0) circuit.measure(2, 1) circuit.x(2).c_if(cr, 2) - self.circuit_drawer( - circuit, cregbundle=False, reverse_bits=True, filename="reverse_bits_cond_true.png" + + fname = "reverse_bits_cond_true.png" + self.circuit_drawer(circuit, cregbundle=False, reverse_bits=True, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, ) - self.circuit_drawer( - circuit, cregbundle=False, reverse_bits=False, filename="reverse_bits_cond_false.png" + fname2 = "reverse_bits_cond_false.png" + self.circuit_drawer(circuit, cregbundle=False, reverse_bits=False, filename=fname2) + + ratio2 = VisualTestUtilities._save_diff( + self._image_path(fname2), + self._reference_path(fname2), + fname2, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, ) + self.assertEqual(ratio, 1) + self.assertEqual(ratio2, 1) + def test_style_custom_gates(self): """Tests style for custom gates""" @@ -700,15 +1115,25 @@ def cnotnot(gate_label): circuit.append(cnotnot("CNOTNOT_PRIME"), [q[0], q[1], q[2]]) circuit.h(q[0]) + fname = "style_custom_gates.png" self.circuit_drawer( circuit, style={ "displaycolor": {"CNOTNOT": ("#000000", "#FFFFFF"), "h": ("#A1A1A1", "#043812")}, "displaytext": {"CNOTNOT_PRIME": "$\\mathrm{CNOTNOT}'$"}, }, - filename="style_custom_gates.png", + filename=fname, ) + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) + def test_6095(self): """Tests controlled-phase gate style See https://github.com/Qiskit/qiskit-terra/issues/6095""" @@ -716,11 +1141,21 @@ def test_6095(self): circuit.cp(1.0, 0, 1) circuit.h(1) + fname = "6095.png" self.circuit_drawer( circuit, style={"displaycolor": {"cp": ("#A27486", "#000000"), "h": ("#A27486", "#000000")}}, - filename="6095.png", + filename=fname, + ) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, ) + self.assertEqual(ratio, 1) def test_instruction_1q_1c(self): """Tests q0-cr0 instruction on a circuit""" @@ -729,7 +1164,18 @@ def test_instruction_1q_1c(self): circuit = QuantumCircuit(qr, cr) inst = QuantumCircuit(1, 1, name="Inst").to_instruction() circuit.append(inst, [qr[0]], [cr[0]]) - self.circuit_drawer(circuit, filename="instruction_1q_1c.png") + + fname = "instruction_1q_1c.png" + self.circuit_drawer(circuit, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_instruction_3q_3c_circ1(self): """Tests q0-q1-q2-cr_20-cr0-cr1 instruction on a circuit""" @@ -739,7 +1185,18 @@ def test_instruction_3q_3c_circ1(self): circuit = QuantumCircuit(qr, cr, cr2) inst = QuantumCircuit(3, 3, name="Inst").to_instruction() circuit.append(inst, [qr[0], qr[1], qr[2]], [cr2[0], cr[0], cr[1]]) - self.circuit_drawer(circuit, filename="instruction_3q_3c_circ1.png") + + fname = "instruction_3q_3c_circ1.png" + self.circuit_drawer(circuit, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_instruction_3q_3c_circ2(self): """Tests q3-q0-q2-cr0-cr1-cr_20 instruction on a circuit""" @@ -749,7 +1206,18 @@ def test_instruction_3q_3c_circ2(self): circuit = QuantumCircuit(qr, cr, cr2) inst = QuantumCircuit(3, 3, name="Inst").to_instruction() circuit.append(inst, [qr[3], qr[0], qr[2]], [cr[0], cr[1], cr2[0]]) - self.circuit_drawer(circuit, filename="instruction_3q_3c_circ2.png") + + fname = "instruction_3q_3c_circ2.png" + self.circuit_drawer(circuit, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_instruction_3q_3c_circ3(self): """Tests q3-q1-q2-cr_31-cr1-cr_30 instruction on a circuit""" @@ -760,7 +1228,18 @@ def test_instruction_3q_3c_circ3(self): circuit = QuantumCircuit(qr, cr, cr2, cr3) inst = QuantumCircuit(3, 3, name="Inst").to_instruction() circuit.append(inst, [qr[3], qr[1], qr[2]], [cr3[1], cr[1], cr3[0]]) - self.circuit_drawer(circuit, filename="instruction_3q_3c_circ3.png") + + fname = "instruction_3q_3c_circ3.png" + self.circuit_drawer(circuit, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_overwide_gates(self): """Test gates don't exceed width of default fold""" @@ -768,7 +1247,18 @@ def test_overwide_gates(self): initial_state = np.zeros(2**5) initial_state[5] = 1 circuit.initialize(initial_state) - self.circuit_drawer(circuit, filename="wide_params.png") + + fname = "wide_params.png" + self.circuit_drawer(circuit, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_one_bit_regs(self): """Test registers with only one bit display without number""" @@ -779,7 +1269,18 @@ def test_one_bit_regs(self): circuit = QuantumCircuit(qr1, qr2, cr1, cr2) circuit.h(0) circuit.measure(0, 0) - self.circuit_drawer(circuit, cregbundle=False, filename="one_bit_regs.png") + + fname = "one_bit_regs.png" + self.circuit_drawer(circuit, cregbundle=False, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_user_ax_subplot(self): """Test for when user supplies ax for a subplot""" @@ -797,7 +1298,18 @@ def test_user_ax_subplot(self): circuit.h(1) circuit.cx(1, 2) plt.close(fig) - self.circuit_drawer(circuit, ax=ax2, filename="user_ax.png") + + fname = "user_ax.png" + self.circuit_drawer(circuit, ax=ax2, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_figwidth(self): """Test style dict 'figwidth'""" @@ -807,7 +1319,18 @@ def test_figwidth(self): circuit.x(1) circuit.cx(1, 2) circuit.x(2) - self.circuit_drawer(circuit, style={"figwidth": 5}, filename="figwidth.png") + + fname = "figwidth.png" + self.circuit_drawer(circuit, style={"figwidth": 5}, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_registerless_one_bit(self): """Test circuit with one-bit registers and registerless bits.""" @@ -815,7 +1338,18 @@ def test_registerless_one_bit(self): qry = QuantumRegister(1, "qry") crx = ClassicalRegister(2, "crx") circuit = QuantumCircuit(qrx, [Qubit(), Qubit()], qry, [Clbit(), Clbit()], crx) - self.circuit_drawer(circuit, filename="registerless_one_bit.png") + + fname = "registerless_one_bit.png" + self.circuit_drawer(circuit, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_measures_with_conditions(self): """Test that a measure containing a condition displays""" @@ -828,8 +1362,30 @@ def test_measures_with_conditions(self): circuit.measure(0, cr1[1]) circuit.measure(1, cr2[0]).c_if(cr1, 1) circuit.h(0).c_if(cr2, 3) - self.circuit_drawer(circuit, cregbundle=False, filename="measure_cond_false.png") - self.circuit_drawer(circuit, cregbundle=True, filename="measure_cond_true.png") + + fname = "measure_cond_false.png" + self.circuit_drawer(circuit, cregbundle=False, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + fname2 = "measure_cond_true.png" + self.circuit_drawer(circuit, cregbundle=True, filename=fname2) + + ratio2 = VisualTestUtilities._save_diff( + self._image_path(fname2), + self._reference_path(fname2), + fname2, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + + self.assertEqual(ratio, 1) + self.assertEqual(ratio2, 1) def test_conditions_measures_with_bits(self): """Test that gates with conditions and measures work with bits""" @@ -839,8 +1395,30 @@ def test_conditions_measures_with_bits(self): circuit = QuantumCircuit(bits, cr, [Clbit()], crx) circuit.x(0).c_if(crx[1], 0) circuit.measure(0, bits[3]) - self.circuit_drawer(circuit, cregbundle=False, filename="measure_cond_bits_false.png") - self.circuit_drawer(circuit, cregbundle=True, filename="measure_cond_bits_true.png") + + fname = "measure_cond_bits_false.png" + self.circuit_drawer(circuit, cregbundle=False, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + fname2 = "measure_cond_bits_true.png" + self.circuit_drawer(circuit, cregbundle=True, filename=fname2) + + ratio2 = VisualTestUtilities._save_diff( + self._image_path(fname2), + self._reference_path(fname2), + fname2, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + + self.assertEqual(ratio, 1) + self.assertEqual(ratio2, 1) def test_conditional_gates_right_of_measures_with_bits(self): """Test that gates with conditions draw to right of measures when same bit""" @@ -851,7 +1429,18 @@ def test_conditional_gates_right_of_measures_with_bits(self): circuit.measure(qr[0], cr[1]) circuit.h(qr[1]).c_if(cr[1], 0) circuit.h(qr[2]).c_if(cr[0], 0) - self.circuit_drawer(circuit, cregbundle=False, filename="measure_cond_bits_right.png") + + fname = "measure_cond_bits_right.png" + self.circuit_drawer(circuit, cregbundle=False, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_conditions_with_bits_reverse(self): """Test that gates with conditions work with bits reversed""" @@ -860,9 +1449,18 @@ def test_conditions_with_bits_reverse(self): crx = ClassicalRegister(2, "cs") circuit = QuantumCircuit(bits, cr, [Clbit()], crx) circuit.x(0).c_if(bits[3], 0) - self.circuit_drawer( - circuit, cregbundle=False, reverse_bits=True, filename="cond_bits_reverse.png" + + fname = "cond_bits_reverse.png" + self.circuit_drawer(circuit, cregbundle=False, reverse_bits=True, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, ) + self.assertEqual(ratio, 1) def test_sidetext_with_condition(self): """Test that sidetext gates align properly with conditions""" @@ -870,7 +1468,18 @@ def test_sidetext_with_condition(self): cr = ClassicalRegister(2, "c") circuit = QuantumCircuit(qr, cr) circuit.append(CPhaseGate(pi / 2), [qr[0], qr[1]]).c_if(cr[1], 1) - self.circuit_drawer(circuit, cregbundle=False, filename="sidetext_condition.png") + + fname = "sidetext_condition.png" + self.circuit_drawer(circuit, cregbundle=False, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_fold_with_conditions(self): """Test that gates with conditions draw correctly when folding""" @@ -894,14 +1503,36 @@ def test_fold_with_conditions(self): circuit.append(U1Gate(0).control(1), [1, 0]).c_if(cr, 27) circuit.append(U1Gate(0).control(1), [1, 0]).c_if(cr, 29) circuit.append(U1Gate(0).control(1), [1, 0]).c_if(cr, 31) - self.circuit_drawer(circuit, cregbundle=False, filename="fold_with_conditions.png") + + fname = "fold_with_conditions.png" + self.circuit_drawer(circuit, cregbundle=False, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_idle_wires_barrier(self): """Test that idle_wires False works with barrier""" circuit = QuantumCircuit(4, 4) circuit.x(2) circuit.barrier() - self.circuit_drawer(circuit, cregbundle=False, filename="idle_wires_barrier.png") + + fname = "idle_wires_barrier.png" + self.circuit_drawer(circuit, cregbundle=False, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) def test_wire_order(self): """Test the wire_order option""" @@ -913,13 +1544,24 @@ def test_wire_order(self): circuit.h(3) circuit.x(1) circuit.x(3).c_if(cr, 10) + + fname = "wire_order.png" self.circuit_drawer( circuit, cregbundle=False, wire_order=[2, 1, 3, 0, 6, 8, 9, 5, 4, 7], - filename="wire_order.png", + filename=fname, ) + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) + def test_barrier_label(self): """Test the barrier label""" circuit = QuantumCircuit(2) @@ -929,8 +1571,19 @@ def test_barrier_label(self): circuit.y(0) circuit.x(1) circuit.barrier(label="End Y/X") + + fname = "barrier_label.png" self.circuit_drawer(circuit, filename="barrier_label.png") + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) + if __name__ == "__main__": unittest.main(verbosity=1) diff --git a/test/ipynb/mpl/circuit/user_style.json b/test/visual/mpl/circuit/user_style.json similarity index 100% rename from test/ipynb/mpl/circuit/user_style.json rename to test/visual/mpl/circuit/user_style.json diff --git a/test/ipynb/mpl/graph/__init__.py b/test/visual/mpl/graph/__init__.py similarity index 71% rename from test/ipynb/mpl/graph/__init__.py rename to test/visual/mpl/graph/__init__.py index f9d8a5f9d8ef..a62c3b834150 100644 --- a/test/ipynb/mpl/graph/__init__.py +++ b/test/visual/mpl/graph/__init__.py @@ -10,7 +10,4 @@ # copyright notice, and modified files need to carry a notice indicating # that they have been altered from the originals. -"""Image comparison test for MPL graph drawer. -You can generate the image references with Binder -in https://mybinder.org/v2/gh///?urlpath=apps/test/ipynb/mpl_tester.ipynb -""" +"""Image comparison test for MPL graph drawer.""" diff --git a/test/visual/mpl/graph/references/16_qubit_gate_map.png b/test/visual/mpl/graph/references/16_qubit_gate_map.png new file mode 100644 index 000000000000..632fe59ce182 Binary files /dev/null and b/test/visual/mpl/graph/references/16_qubit_gate_map.png differ diff --git a/test/visual/mpl/graph/references/1_qubit_gate_map.png b/test/visual/mpl/graph/references/1_qubit_gate_map.png new file mode 100644 index 000000000000..9d770a0d6597 Binary files /dev/null and b/test/visual/mpl/graph/references/1_qubit_gate_map.png differ diff --git a/test/visual/mpl/graph/references/27_qubit_gate_map.png b/test/visual/mpl/graph/references/27_qubit_gate_map.png new file mode 100644 index 000000000000..b81ee4619395 Binary files /dev/null and b/test/visual/mpl/graph/references/27_qubit_gate_map.png differ diff --git a/test/visual/mpl/graph/references/5_qubit_gate_map.png b/test/visual/mpl/graph/references/5_qubit_gate_map.png new file mode 100644 index 000000000000..8c50538a795c Binary files /dev/null and b/test/visual/mpl/graph/references/5_qubit_gate_map.png differ diff --git a/test/visual/mpl/graph/references/65_qubit_gate_map.png b/test/visual/mpl/graph/references/65_qubit_gate_map.png new file mode 100644 index 000000000000..88f540e69bb9 Binary files /dev/null and b/test/visual/mpl/graph/references/65_qubit_gate_map.png differ diff --git a/test/visual/mpl/graph/references/7_qubit_gate_map.png b/test/visual/mpl/graph/references/7_qubit_gate_map.png new file mode 100644 index 000000000000..543e9159a317 Binary files /dev/null and b/test/visual/mpl/graph/references/7_qubit_gate_map.png differ diff --git a/test/visual/mpl/graph/references/bloch_multivector.png b/test/visual/mpl/graph/references/bloch_multivector.png new file mode 100644 index 000000000000..5b72a9d04896 Binary files /dev/null and b/test/visual/mpl/graph/references/bloch_multivector.png differ diff --git a/test/visual/mpl/graph/references/bloch_multivector_figsize_improvements.png b/test/visual/mpl/graph/references/bloch_multivector_figsize_improvements.png new file mode 100644 index 000000000000..80e73131a39b Binary files /dev/null and b/test/visual/mpl/graph/references/bloch_multivector_figsize_improvements.png differ diff --git a/test/visual/mpl/graph/references/coupling_map.png b/test/visual/mpl/graph/references/coupling_map.png new file mode 100644 index 000000000000..f5e51efea127 Binary files /dev/null and b/test/visual/mpl/graph/references/coupling_map.png differ diff --git a/test/visual/mpl/graph/references/figsize.png b/test/visual/mpl/graph/references/figsize.png new file mode 100644 index 000000000000..25ece4b5696d Binary files /dev/null and b/test/visual/mpl/graph/references/figsize.png differ diff --git a/test/visual/mpl/graph/references/font_color.png b/test/visual/mpl/graph/references/font_color.png new file mode 100644 index 000000000000..6fef2274d9dc Binary files /dev/null and b/test/visual/mpl/graph/references/font_color.png differ diff --git a/test/visual/mpl/graph/references/hinton.png b/test/visual/mpl/graph/references/hinton.png new file mode 100644 index 000000000000..3be80df31480 Binary files /dev/null and b/test/visual/mpl/graph/references/hinton.png differ diff --git a/test/visual/mpl/graph/references/histogram.png b/test/visual/mpl/graph/references/histogram.png new file mode 100644 index 000000000000..1d11b0d110ce Binary files /dev/null and b/test/visual/mpl/graph/references/histogram.png differ diff --git a/test/visual/mpl/graph/references/histogram_2_sets_with_rest.png b/test/visual/mpl/graph/references/histogram_2_sets_with_rest.png new file mode 100644 index 000000000000..ab02566c1561 Binary files /dev/null and b/test/visual/mpl/graph/references/histogram_2_sets_with_rest.png differ diff --git a/test/visual/mpl/graph/references/histogram_color.png b/test/visual/mpl/graph/references/histogram_color.png new file mode 100644 index 000000000000..48890f468c7f Binary files /dev/null and b/test/visual/mpl/graph/references/histogram_color.png differ diff --git a/test/visual/mpl/graph/references/histogram_desc_value_sort.png b/test/visual/mpl/graph/references/histogram_desc_value_sort.png new file mode 100644 index 000000000000..4a963ff40212 Binary files /dev/null and b/test/visual/mpl/graph/references/histogram_desc_value_sort.png differ diff --git a/test/visual/mpl/graph/references/histogram_hamming.png b/test/visual/mpl/graph/references/histogram_hamming.png new file mode 100644 index 000000000000..12ed9e6418e2 Binary files /dev/null and b/test/visual/mpl/graph/references/histogram_hamming.png differ diff --git a/test/visual/mpl/graph/references/histogram_legend.png b/test/visual/mpl/graph/references/histogram_legend.png new file mode 100644 index 000000000000..daa61cdeeb43 Binary files /dev/null and b/test/visual/mpl/graph/references/histogram_legend.png differ diff --git a/test/visual/mpl/graph/references/histogram_multiple_colors.png b/test/visual/mpl/graph/references/histogram_multiple_colors.png new file mode 100644 index 000000000000..c1ecd9aef02e Binary files /dev/null and b/test/visual/mpl/graph/references/histogram_multiple_colors.png differ diff --git a/test/visual/mpl/graph/references/histogram_title.png b/test/visual/mpl/graph/references/histogram_title.png new file mode 100644 index 000000000000..cf72f4181c12 Binary files /dev/null and b/test/visual/mpl/graph/references/histogram_title.png differ diff --git a/test/visual/mpl/graph/references/histogram_value_sort.png b/test/visual/mpl/graph/references/histogram_value_sort.png new file mode 100644 index 000000000000..df5328ef884c Binary files /dev/null and b/test/visual/mpl/graph/references/histogram_value_sort.png differ diff --git a/test/visual/mpl/graph/references/histogram_with_rest.png b/test/visual/mpl/graph/references/histogram_with_rest.png new file mode 100644 index 000000000000..baecf1b96bd4 Binary files /dev/null and b/test/visual/mpl/graph/references/histogram_with_rest.png differ diff --git a/test/visual/mpl/graph/references/line_color.png b/test/visual/mpl/graph/references/line_color.png new file mode 100644 index 000000000000..a28d508afa36 Binary files /dev/null and b/test/visual/mpl/graph/references/line_color.png differ diff --git a/test/visual/mpl/graph/references/paulivec.png b/test/visual/mpl/graph/references/paulivec.png new file mode 100644 index 000000000000..2abce570686b Binary files /dev/null and b/test/visual/mpl/graph/references/paulivec.png differ diff --git a/test/visual/mpl/graph/references/qsphere.png b/test/visual/mpl/graph/references/qsphere.png new file mode 100644 index 000000000000..f344accd2856 Binary files /dev/null and b/test/visual/mpl/graph/references/qsphere.png differ diff --git a/test/visual/mpl/graph/references/qubit_color.png b/test/visual/mpl/graph/references/qubit_color.png new file mode 100644 index 000000000000..caf5631ff2d3 Binary files /dev/null and b/test/visual/mpl/graph/references/qubit_color.png differ diff --git a/test/visual/mpl/graph/references/qubit_labels.png b/test/visual/mpl/graph/references/qubit_labels.png new file mode 100644 index 000000000000..6a42e1176390 Binary files /dev/null and b/test/visual/mpl/graph/references/qubit_labels.png differ diff --git a/test/visual/mpl/graph/references/qubit_size.png b/test/visual/mpl/graph/references/qubit_size.png new file mode 100644 index 000000000000..d66a174d1032 Binary files /dev/null and b/test/visual/mpl/graph/references/qubit_size.png differ diff --git a/test/visual/mpl/graph/references/state_city.png b/test/visual/mpl/graph/references/state_city.png new file mode 100644 index 000000000000..52efe9911a8b Binary files /dev/null and b/test/visual/mpl/graph/references/state_city.png differ diff --git a/test/visual/mpl/graph/test_graph_matplotlib_drawer.py b/test/visual/mpl/graph/test_graph_matplotlib_drawer.py new file mode 100644 index 000000000000..0bf9ee918481 --- /dev/null +++ b/test/visual/mpl/graph/test_graph_matplotlib_drawer.py @@ -0,0 +1,677 @@ +# This code is part of Qiskit. +# +# (C) Copyright IBM 2020. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. + +"""Tests for graph MPL drawer""" + +import unittest +import os +from test.visual import VisualTestUtilities +from contextlib import contextmanager +from pathlib import Path + +from qiskit import BasicAer, execute +from qiskit.test import QiskitTestCase +from qiskit import QuantumCircuit +from qiskit.utils import optionals +from qiskit.visualization.state_visualization import state_drawer +from qiskit.visualization.counts_visualization import plot_histogram +from qiskit.visualization.gate_map import plot_gate_map, plot_coupling_map +from qiskit.providers.fake_provider import ( + FakeArmonk, + FakeBelem, + FakeCasablanca, + FakeRueschlikon, + FakeMumbai, + FakeManhattan, +) + +if optionals.HAS_MATPLOTLIB: + from matplotlib.pyplot import close as mpl_close +else: + raise ImportError('Must have Matplotlib installed. To install, run "pip install matplotlib".') + +BASE_DIR = Path(__file__).parent +RESULT_DIR = Path(BASE_DIR) / "graph_results" +TEST_REFERENCE_DIR = Path(BASE_DIR) / "references" +FAILURE_DIFF_DIR = Path(BASE_DIR).parent / "visual_test_failures" +FAILURE_PREFIX = "graph_failure_" + + +@contextmanager +def cwd(path): + """A context manager to run in a particular path""" + oldpwd = os.getcwd() + os.chdir(path) + try: + yield + finally: + os.chdir(oldpwd) + + +class TestGraphMatplotlibDrawer(QiskitTestCase): + """Graph MPL visualization""" + + def setUp(self): + super().setUp() + self.graph_state_drawer = VisualTestUtilities.save_data_wrap( + state_drawer, str(self), RESULT_DIR + ) + self.graph_count_drawer = VisualTestUtilities.save_data_wrap( + plot_histogram, str(self), RESULT_DIR + ) + self.graph_plot_gate_map = VisualTestUtilities.save_data_wrap( + plot_gate_map, str(self), RESULT_DIR + ) + self.graph_plot_coupling_map = VisualTestUtilities.save_data_wrap( + plot_coupling_map, str(self), RESULT_DIR + ) + + if not os.path.exists(FAILURE_DIFF_DIR): + os.makedirs(FAILURE_DIFF_DIR) + + if not os.path.exists(RESULT_DIR): + os.makedirs(RESULT_DIR) + + def tearDown(self): + super().tearDown() + mpl_close("all") + + @staticmethod + def _image_path(image_name): + return os.path.join(RESULT_DIR, image_name) + + @staticmethod + def _reference_path(image_name): + return os.path.join(TEST_REFERENCE_DIR, image_name) + + def test_plot_bloch_multivector(self): + """test bloch sphere + See https://github.com/Qiskit/qiskit-terra/issues/6397. + """ + circuit = QuantumCircuit(1) + circuit.h(0) + + # getting the state using backend + backend = BasicAer.get_backend("statevector_simulator") + result = execute(circuit, backend).result() + state = result.get_statevector(circuit) + + fname = "bloch_multivector.png" + self.graph_state_drawer(state=state, output="bloch", filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) + + def test_plot_state_hinton(self): + """test plot_state_hinton""" + circuit = QuantumCircuit(1) + circuit.x(0) + + # getting the state using backend + backend = BasicAer.get_backend("statevector_simulator") + result = execute(circuit, backend).result() + state = result.get_statevector(circuit) + + fname = "hinton.png" + self.graph_state_drawer(state=state, output="hinton", filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) + + def test_plot_state_qsphere(self): + """test for plot_state_qsphere""" + circuit = QuantumCircuit(1) + circuit.x(0) + + # getting the state using backend + backend = BasicAer.get_backend("statevector_simulator") + result = execute(circuit, backend).result() + state = result.get_statevector(circuit) + + fname = "qsphere.png" + self.graph_state_drawer(state=state, output="qsphere", filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) + + def test_plot_state_city(self): + """test for plot_state_city""" + circuit = QuantumCircuit(1) + circuit.x(0) + + # getting the state using backend + backend = BasicAer.get_backend("statevector_simulator") + result = execute(circuit, backend).result() + state = result.get_statevector(circuit) + + fname = "state_city.png" + self.graph_state_drawer(state=state, output="city", filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) + + def test_plot_state_paulivec(self): + """test for plot_state_paulivec""" + circuit = QuantumCircuit(1) + circuit.x(0) + + # getting the state using backend + backend = BasicAer.get_backend("statevector_simulator") + result = execute(circuit, backend).result() + state = result.get_statevector(circuit) + + fname = "paulivec.png" + self.graph_state_drawer(state=state, output="paulivec", filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) + + def test_plot_histogram(self): + """for testing the plot_histogram""" + # specifing counts because we do not want oscillation of + # result until a changes is made to plot_histogram + + counts = {"11": 500, "00": 500} + + fname = "histogram.png" + self.graph_count_drawer(counts, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) + + def test_plot_histogram_with_rest(self): + """test plot_histogram with 2 datasets and number_to_keep""" + data = [{"00": 3, "01": 5, "10": 6, "11": 12}] + + fname = "histogram_with_rest.png" + self.graph_count_drawer(data, number_to_keep=2, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) + + def test_plot_histogram_2_sets_with_rest(self): + """test plot_histogram with 2 datasets and number_to_keep""" + data = [ + {"00": 3, "01": 5, "10": 6, "11": 12}, + {"00": 5, "01": 7, "10": 6, "11": 12}, + ] + + fname = "histogram_2_sets_with_rest.png" + self.graph_count_drawer(data, number_to_keep=2, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) + + def test_plot_histogram_color(self): + """Test histogram with single color""" + + counts = {"00": 500, "11": 500} + + fname = "histogram_color.png" + self.graph_count_drawer(data=counts, color="#204940", filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) + + def test_plot_histogram_multiple_colors(self): + """Test histogram with multiple custom colors""" + + counts = [ + {"00": 10, "01": 15, "10": 20, "11": 25}, + {"00": 25, "01": 20, "10": 15, "11": 10}, + ] + + fname = "histogram_multiple_colors.png" + self.graph_count_drawer( + data=counts, + color=["#204940", "#c26219"], + filename=fname, + ) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) + + def test_plot_histogram_hamming(self): + """Test histogram with hamming distance""" + + counts = {"101": 500, "010": 500, "001": 500, "100": 500} + + fname = "histogram_hamming.png" + self.graph_count_drawer(data=counts, sort="hamming", target_string="101", filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) + + def test_plot_histogram_value_sort(self): + """Test histogram with sorting by value""" + + counts = {"101": 300, "010": 240, "001": 80, "100": 150, "110": 160, "000": 280, "111": 60} + + fname = "histogram_value_sort.png" + self.graph_count_drawer(data=counts, sort="value", target_string="000", filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) + + def test_plot_histogram_desc_value_sort(self): + """Test histogram with sorting by descending value""" + + counts = {"101": 150, "010": 50, "001": 180, "100": 10, "110": 190, "000": 80, "111": 260} + + fname = "histogram_desc_value_sort.png" + self.graph_count_drawer( + data=counts, + sort="value_desc", + target_string="000", + filename=fname, + ) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) + + def test_plot_histogram_legend(self): + """Test histogram with legend""" + + counts = [{"0": 50, "1": 30}, {"0": 30, "1": 40}] + + fname = "histogram_legend.png" + self.graph_count_drawer( + data=counts, + legend=["first", "second"], + filename=fname, + figsize=(15, 5), + ) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) + + def test_plot_histogram_title(self): + """Test histogram with title""" + + counts = [{"0": 50, "1": 30}, {"0": 30, "1": 40}] + + fname = "histogram_title.png" + self.graph_count_drawer(data=counts, title="My Histogram", filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) + + def test_plot_1_qubit_gate_map(self): + """Test plot_gate_map using 1 qubit backend""" + # getting the mock backend from FakeProvider + + backend = FakeArmonk() + + fname = "1_qubit_gate_map.png" + self.graph_plot_gate_map(backend=backend, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) + + def test_plot_5_qubit_gate_map(self): + """Test plot_gate_map using 5 qubit backend""" + # getting the mock backend from FakeProvider + + backend = FakeBelem() + + fname = "5_qubit_gate_map.png" + self.graph_plot_gate_map(backend=backend, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) + + def test_plot_7_qubit_gate_map(self): + """Test plot_gate_map using 7 qubit backend""" + # getting the mock backend from FakeProvider + + backend = FakeCasablanca() + + fname = "7_qubit_gate_map.png" + self.graph_plot_gate_map(backend=backend, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) + + def test_plot_16_qubit_gate_map(self): + """Test plot_gate_map using 16 qubit backend""" + # getting the mock backend from FakeProvider + + backend = FakeRueschlikon() + + fname = "16_qubit_gate_map.png" + self.graph_plot_gate_map(backend=backend, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) + + def test_plot_27_qubit_gate_map(self): + """Test plot_gate_map using 27 qubit backend""" + # getting the mock backend from FakeProvider + + backend = FakeMumbai() + + fname = "27_qubit_gate_map.png" + self.graph_plot_gate_map(backend=backend, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) + + def test_plot_65_qubit_gate_map(self): + """test for plot_gate_map using 65 qubit backend""" + # getting the mock backend from FakeProvider + + backend = FakeManhattan() + + fname = "65_qubit_gate_map.png" + self.graph_plot_gate_map(backend=backend, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) + + def test_figsize(self): + """Test figsize parameter of plot_gate_map""" + # getting the mock backend from FakeProvider + + backend = FakeBelem() + + fname = "figsize.png" + self.graph_plot_gate_map(backend=backend, figsize=(10, 10), filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) + + def test_qubit_size(self): + """Test qubit_size parameter of plot_gate_map""" + # getting the mock backend from FakeProvider + + backend = FakeBelem() + + fname = "qubit_size.png" + self.graph_plot_gate_map(backend=backend, qubit_size=38, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) + + def test_qubit_color(self): + """Test qubit_color parameter of plot_gate_map""" + # getting the mock backend from FakeProvider + + backend = FakeCasablanca() + + fname = "qubit_color.png" + self.graph_plot_gate_map(backend=backend, qubit_color=["#ff0000"] * 7, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) + + def test_qubit_labels(self): + """Test qubit_labels parameter of plot_gate_map""" + # getting the mock backend from FakeProvider + + backend = FakeCasablanca() + + fname = "qubit_labels.png" + self.graph_plot_gate_map( + backend=backend, qubit_labels=list(range(10, 17, 1)), filename=fname + ) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) + + def test_line_color(self): + """Test line_color parameter of plot_gate_map""" + # getting the mock backend from FakeProvider + + backend = FakeManhattan() + + fname = "line_color.png" + self.graph_plot_gate_map(backend=backend, line_color=["#00ff00"] * 144, filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) + + def test_font_color(self): + """Test font_color parameter of plot_gate_map""" + # getting the mock backend from FakeProvider + + backend = FakeManhattan() + + fname = "font_color.png" + self.graph_plot_gate_map(backend=backend, font_color="#ff00ff", filename=fname) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) + + def test_plot_coupling_map(self): + """Test plot_coupling_map""" + + num_qubits = 5 + qubit_coordinates = [[1, 0], [0, 1], [1, 1], [1, 2], [2, 1]] + coupling_map = [[1, 0], [1, 2], [1, 3], [3, 4]] + + fname = "coupling_map.png" + self.graph_plot_coupling_map( + num_qubits=num_qubits, + qubit_coordinates=qubit_coordinates, + coupling_map=coupling_map, + filename=fname, + ) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) + + 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) + + fname = "bloch_multivector_figsize_improvements.png" + 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=fname, + ) + + ratio = VisualTestUtilities._save_diff( + self._image_path(fname), + self._reference_path(fname), + fname, + FAILURE_DIFF_DIR, + FAILURE_PREFIX, + ) + self.assertEqual(ratio, 1) + + +if __name__ == "__main__": + unittest.main(verbosity=1) diff --git a/test/ipynb/mpl_tester.ipynb b/test/visual/mpl_tester.ipynb similarity index 100% rename from test/ipynb/mpl_tester.ipynb rename to test/visual/mpl_tester.ipynb diff --git a/test/ipynb/results.py b/test/visual/results.py similarity index 88% rename from test/ipynb/results.py rename to test/visual/results.py index cf8fb3ebc660..efaf09bbbbfa 100644 --- a/test/ipynb/results.py +++ b/test/visual/results.py @@ -14,7 +14,6 @@ import os import json -import zipfile from PIL import Image, ImageChops, ImageDraw SWD = os.path.dirname(os.path.abspath(__file__)) @@ -81,12 +80,6 @@ def _new_gray(size, color): drawing.rectangle((0, 0) + size, color) return img - @staticmethod - def _zipfiles(files, zipname): - with zipfile.ZipFile(zipname, "w", zipfile.ZIP_DEFLATED) as zipf: - for file_ in files: - zipf.write(file_, arcname=os.path.basename(file_)) - @staticmethod def passed_result_html(result, reference, diff, title): """Creates the html for passing tests""" @@ -142,26 +135,6 @@ def diff_images(self): self.data[name]["diff_name"] = diff_name self.data[name]["title"] = title - def summary(self): - """Creates the html for the header""" - ret = "" - - if len(self.mismatch) >= 2: - Results._zipfiles(self.mismatch, f"{self.directory}/mismatch.zip") - ret += ( - f'" % len(self.mismatch) - ) - - if len(self.missing) >= 2: - Results._zipfiles(self.missing, f"{self.directory}/missing.zip") - ret += ( - f'" % len(self.missing) - ) - - return ret - def _repr_html_(self): ret = self.summary() ret += "
"