Repository: Qiskit/qiskit

Issue:
image comparison to CI
We need a way to test image comparison in CI, because with [the current approach](https://github.com/Qiskit/qiskit-terra/pull/4544) it is very easy to introduce regressions.

We [used to have this](https://github.com/Qiskit/qiskit-terra/pull/5108), but I cannot remember why we dropped it.

It should be able to run the test in a CI (in an env that we can call the standard one, with a single source of truth for reference images).

- [ ] `git mv test/ipynb test/visual`
- [ ] Run `mpl/graph/test_graph_matplotlib_drawer.py` and `mpl/circuit/test_circuit_matplotlib_drawer.py` in CI (either GitHub Action or Azure)
- [ ] create downloadable artefacts for "result" and "diff" images when there is a difference
- [ ] (optional)  extend coverage  would be great


Discussion:
Feel free to assign this to me @1ucian0 

Resolving patch:
diff --git a/qiskit/visualization/state_visualization.py b/qiskit/visualization/state_visualization.py
--- 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):


Test patch:
diff --git a/test/ipynb/mpl/circuit/__init__.py b/test/ipynb/mpl/circuit/__init__.py
deleted file mode 100644
--- 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/<user>/<repo>/<branch>?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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
--- 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
--- /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
--- 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/<user>/<repo>/<branch>?urlpath=apps/test/ipynb/<nb_name>.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
--- 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/<user>/<repo>/<branch>?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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
--- 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
--- 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/<user>/<repo>/<branch>?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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
--- /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
--- 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'<div><a href="{self.directory}/mismatch.zip">'
-                "Download %s mismatch results as a zip</a></div>" % len(self.mismatch)
-            )
-
-        if len(self.missing) >= 2:
-            Results._zipfiles(self.missing, f"{self.directory}/missing.zip")
-            ret += (
-                f'<div><a href="{self.directory}/missing.zip">'
-                "Download %s missing results as a zip</a></div>" % len(self.missing)
-            )
-
-        return ret
-
     def _repr_html_(self):
         ret = self.summary()
         ret += "<div>"