def plot_bloch_vector(bloch, title="", ax=None, figsize=None, coord_type="cartesian"): """Plot the Bloch sphere. Plot a sphere, axes, the Bloch vector, and its projections onto each axis. Args: bloch (list[double]): array of three elements where [<x>, <y>, <z>] (Cartesian) or [<r>, <theta>, <phi>] (spherical in radians) <theta> is inclination angle from +z direction <phi> is azimuth from +x direction title (str): a string that represents the plot title ax (matplotlib.axes.Axes): An Axes to use for rendering the bloch sphere figsize (tuple): Figure size in inches. Has no effect is passing ``ax``. coord_type (str): a string that specifies coordinate type for bloch (Cartesian or spherical), default is Cartesian Returns: Figure: A matplotlib figure instance if ``ax = None``. Raises: MissingOptionalLibraryError: Requires matplotlib. Example: .. jupyter-execute:: from qiskit.visualization import plot_bloch_vector %matplotlib inline plot_bloch_vector([0,1,0], title="New Bloch Sphere") """ if not HAS_MATPLOTLIB: raise MissingOptionalLibraryError( libname="Matplotlib", name="plot_bloch_vector", pip_install="pip install matplotlib", ) from qiskit.visualization.bloch import Bloch if figsize is None: figsize = (5, 5) B = Bloch(axes=ax) if coord_type == "spherical": r, theta, phi = bloch[0], bloch[1], bloch[2] bloch[0] = r * np.sin(theta) * np.cos(phi) bloch[1] = r * np.sin(theta) * np.sin(phi) bloch[2] = r * np.cos(theta) B.add_vectors(bloch) B.render(title=title) if ax is None: fig = B.fig fig.set_size_inches(figsize[0], figsize[1]) matplotlib_close_if_inline(fig) return fig return None
def get_image(self, interactive: bool = False) -> matplotlib.pyplot.Figure: """Get image data to return. Args: interactive: When set `True` show the circuit in a new window. This depends on the matplotlib backend being used supporting this. Returns: Matplotlib figure data. """ matplotlib_close_if_inline(self.figure) if self.figure and interactive: self.figure.show() return self.figure
def plot_state_qsphere( state, figsize=None, ax=None, show_state_labels=True, show_state_phases=False, use_degrees=False, *, rho=None, filename=None, ): """Plot the qsphere representation of a quantum state. Here, the size of the points is proportional to the probability of the corresponding term in the state and the color represents the phase. Args: state (Statevector or DensityMatrix or ndarray): an N-qubit quantum state. figsize (tuple): Figure size in inches. ax (matplotlib.axes.Axes): An optional Axes object to be used for the visualization output. If none is specified a new matplotlib Figure will be created and used. Additionally, if specified there will be no returned Figure since it is redundant. show_state_labels (bool): An optional boolean indicating whether to show labels for each basis state. show_state_phases (bool): An optional boolean indicating whether to show the phase for each basis state. use_degrees (bool): An optional boolean indicating whether to use radians or degrees for the phase values in the plot. Returns: Figure: A matplotlib figure instance if the ``ax`` kwarg is not set Raises: MissingOptionalLibraryError: Requires matplotlib. VisualizationError: if input is not a valid N-qubit state. QiskitError: Input statevector does not have valid dimensions. Example: .. jupyter-execute:: from qiskit import QuantumCircuit from qiskit.quantum_info import Statevector from qiskit.visualization import plot_state_qsphere %matplotlib inline qc = QuantumCircuit(2) qc.h(0) qc.cx(0, 1) state = Statevector.from_instruction(qc) plot_state_qsphere(state) """ if not HAS_MATPLOTLIB: raise MissingOptionalLibraryError( libname="Matplotlib", name="plot_state_qsphere", pip_install="pip install matplotlib", ) import matplotlib.gridspec as gridspec from matplotlib import pyplot as plt from matplotlib.patches import Circle from qiskit.visualization.bloch import Arrow3D try: import seaborn as sns except ImportError as ex: raise MissingOptionalLibraryError( libname="seaborn", name="plot_state_qsphere", pip_install="pip install seaborn", ) from ex rho = DensityMatrix(state) num = rho.num_qubits if num is None: raise VisualizationError("Input is not a multi-qubit quantum state.") # get the eigenvectors and eigenvalues eigvals, eigvecs = linalg.eigh(rho.data) if figsize is None: figsize = (7, 7) if ax is None: return_fig = True fig = plt.figure(figsize=figsize) else: return_fig = False fig = ax.get_figure() gs = gridspec.GridSpec(nrows=3, ncols=3) ax = fig.add_subplot(gs[0:3, 0:3], projection="3d") ax.axes.set_xlim3d(-1.0, 1.0) ax.axes.set_ylim3d(-1.0, 1.0) ax.axes.set_zlim3d(-1.0, 1.0) ax.axes.grid(False) ax.view_init(elev=5, azim=275) # Force aspect ratio # MPL 3.2 or previous do not have set_box_aspect if hasattr(ax.axes, "set_box_aspect"): ax.axes.set_box_aspect((1, 1, 1)) # start the plotting # Plot semi-transparent sphere u = np.linspace(0, 2 * np.pi, 25) v = np.linspace(0, np.pi, 25) x = np.outer(np.cos(u), np.sin(v)) y = np.outer(np.sin(u), np.sin(v)) z = np.outer(np.ones(np.size(u)), np.cos(v)) ax.plot_surface( x, y, z, rstride=1, cstride=1, color=plt.rcParams["grid.color"], alpha=0.2, linewidth=0 ) # Get rid of the panes ax.w_xaxis.set_pane_color((1.0, 1.0, 1.0, 0.0)) ax.w_yaxis.set_pane_color((1.0, 1.0, 1.0, 0.0)) ax.w_zaxis.set_pane_color((1.0, 1.0, 1.0, 0.0)) # Get rid of the spines ax.w_xaxis.line.set_color((1.0, 1.0, 1.0, 0.0)) ax.w_yaxis.line.set_color((1.0, 1.0, 1.0, 0.0)) ax.w_zaxis.line.set_color((1.0, 1.0, 1.0, 0.0)) # Get rid of the ticks ax.set_xticks([]) ax.set_yticks([]) ax.set_zticks([]) # traversing the eigvals/vecs backward as sorted low->high for idx in range(eigvals.shape[0] - 1, -1, -1): if eigvals[idx] > 0.001: # get the max eigenvalue state = eigvecs[:, idx] loc = np.absolute(state).argmax() # remove the global phase from max element angles = (np.angle(state[loc]) + 2 * np.pi) % (2 * np.pi) angleset = np.exp(-1j * angles) state = angleset * state d = num for i in range(2 ** num): # get x,y,z points element = bin(i)[2:].zfill(num) weight = element.count("1") zvalue = -2 * weight / d + 1 number_of_divisions = n_choose_k(d, weight) weight_order = bit_string_index(element) angle = (float(weight) / d) * (np.pi * 2) + ( weight_order * 2 * (np.pi / number_of_divisions) ) if (weight > d / 2) or ( (weight == d / 2) and (weight_order >= number_of_divisions / 2) ): angle = np.pi - angle - (2 * np.pi / number_of_divisions) xvalue = np.sqrt(1 - zvalue ** 2) * np.cos(angle) yvalue = np.sqrt(1 - zvalue ** 2) * np.sin(angle) # get prob and angle - prob will be shade and angle color prob = np.real(np.dot(state[i], state[i].conj())) prob = min(prob, 1) # See https://github.com/Qiskit/qiskit-terra/issues/4666 colorstate = phase_to_rgb(state[i]) alfa = 1 if yvalue >= 0.1: alfa = 1.0 - yvalue if not np.isclose(prob, 0) and show_state_labels: rprime = 1.3 angle_theta = np.arctan2(np.sqrt(1 - zvalue ** 2), zvalue) xvalue_text = rprime * np.sin(angle_theta) * np.cos(angle) yvalue_text = rprime * np.sin(angle_theta) * np.sin(angle) zvalue_text = rprime * np.cos(angle_theta) element_text = "$\\vert" + element + "\\rangle$" if show_state_phases: element_angle = (np.angle(state[i]) + (np.pi * 4)) % (np.pi * 2) if use_degrees: element_text += "\n$%.1f^\\circ$" % (element_angle * 180 / np.pi) else: element_angle = pi_check(element_angle, ndigits=3).replace("pi", "\\pi") element_text += "\n$%s$" % (element_angle) ax.text( xvalue_text, yvalue_text, zvalue_text, element_text, ha="center", va="center", size=12, ) ax.plot( [xvalue], [yvalue], [zvalue], markerfacecolor=colorstate, markeredgecolor=colorstate, marker="o", markersize=np.sqrt(prob) * 30, alpha=alfa, ) a = Arrow3D( [0, xvalue], [0, yvalue], [0, zvalue], mutation_scale=20, alpha=prob, arrowstyle="-", color=colorstate, lw=2, ) ax.add_artist(a) # add weight lines for weight in range(d + 1): theta = np.linspace(-2 * np.pi, 2 * np.pi, 100) z = -2 * weight / d + 1 r = np.sqrt(1 - z ** 2) x = r * np.cos(theta) y = r * np.sin(theta) ax.plot(x, y, z, color=(0.5, 0.5, 0.5), lw=1, ls=":", alpha=0.5) # add center point ax.plot( [0], [0], [0], markerfacecolor=(0.5, 0.5, 0.5), markeredgecolor=(0.5, 0.5, 0.5), marker="o", markersize=3, alpha=1, ) else: break n = 64 theta = np.ones(n) colors = sns.hls_palette(n) ax2 = fig.add_subplot(gs[2:, 2:]) ax2.pie(theta, colors=colors[5 * n // 8 :] + colors[: 5 * n // 8], radius=0.75) ax2.add_artist(Circle((0, 0), 0.5, color="white", zorder=1)) offset = 0.95 # since radius of sphere is one. if use_degrees: labels = ["Phase\n(Deg)", "0", "90", "180 ", "270"] else: labels = ["Phase", "$0$", "$\\pi/2$", "$\\pi$", "$3\\pi/2$"] ax2.text(0, 0, labels[0], horizontalalignment="center", verticalalignment="center", fontsize=14) ax2.text( offset, 0, labels[1], horizontalalignment="center", verticalalignment="center", fontsize=14 ) ax2.text( 0, offset, labels[2], horizontalalignment="center", verticalalignment="center", fontsize=14 ) ax2.text( -offset, 0, labels[3], horizontalalignment="center", verticalalignment="center", fontsize=14 ) ax2.text( 0, -offset, labels[4], horizontalalignment="center", verticalalignment="center", fontsize=14 ) if return_fig: matplotlib_close_if_inline(fig) if filename is None: return fig else: return fig.savefig(filename)
def plot_state_paulivec( state, title="", figsize=None, color=None, ax=None, *, rho=None, filename=None ): """Plot the paulivec representation of a quantum state. Plot a bargraph of the mixed state rho over the pauli matrices Args: state (Statevector or DensityMatrix or ndarray): an N-qubit quantum state. title (str): a string that represents the plot title figsize (tuple): Figure size in inches. color (list or str): Color of the expectation value bars. ax (matplotlib.axes.Axes): An optional Axes object to be used for the visualization output. If none is specified a new matplotlib Figure will be created and used. Additionally, if specified there will be no returned Figure since it is redundant. Returns: matplotlib.Figure: The matplotlib.Figure of the visualization if the ``ax`` kwarg is not set Raises: MissingOptionalLibraryError: Requires matplotlib. VisualizationError: if input is not a valid N-qubit state. Example: .. jupyter-execute:: from qiskit import QuantumCircuit from qiskit.quantum_info import Statevector from qiskit.visualization import plot_state_paulivec %matplotlib inline qc = QuantumCircuit(2) qc.h(0) qc.cx(0, 1) state = Statevector.from_instruction(qc) plot_state_paulivec(state, color='midnightblue', title="New PauliVec plot") """ if not HAS_MATPLOTLIB: raise MissingOptionalLibraryError( libname="Matplotlib", name="plot_state_paulivec", pip_install="pip install matplotlib", ) from matplotlib import pyplot as plt labels, values = _paulivec_data(state) numelem = len(values) if figsize is None: figsize = (7, 5) if color is None: color = "#648fff" ind = np.arange(numelem) # the x locations for the groups width = 0.5 # the width of the bars if ax is None: return_fig = True fig, ax = plt.subplots(figsize=figsize) else: return_fig = False fig = ax.get_figure() ax.grid(zorder=0, linewidth=1, linestyle="--") ax.bar(ind, values, width, color=color, zorder=2) ax.axhline(linewidth=1, color="k") # add some text for labels, title, and axes ticks ax.set_ylabel("Expectation value", fontsize=14) ax.set_xticks(ind) ax.set_yticks([-1, -0.5, 0, 0.5, 1]) ax.set_xticklabels(labels, fontsize=14, rotation=70) ax.set_xlabel("Pauli", fontsize=14) ax.set_ylim([-1, 1]) ax.set_facecolor("#eeeeee") for tick in ax.xaxis.get_major_ticks() + ax.yaxis.get_major_ticks(): tick.label.set_fontsize(14) ax.set_title(title, fontsize=16) if return_fig: matplotlib_close_if_inline(fig) if filename is None: return fig else: return fig.savefig(filename)
def plot_state_hinton( state, title="", figsize=None, ax_real=None, ax_imag=None, *, rho=None, filename=None ): """Plot a hinton diagram for the density matrix of a quantum state. Args: state (Statevector or DensityMatrix or ndarray): An N-qubit quantum state. title (str): a string that represents the plot title figsize (tuple): Figure size in inches. filename (str): file path to save image to. ax_real (matplotlib.axes.Axes): An optional Axes object to be used for the visualization output. If none is specified a new matplotlib Figure will be created and used. If this is specified without an ax_imag only the real component plot will be generated. Additionally, if specified there will be no returned Figure since it is redundant. ax_imag (matplotlib.axes.Axes): An optional Axes object to be used for the visualization output. If none is specified a new matplotlib Figure will be created and used. If this is specified without an ax_imag only the real component plot will be generated. Additionally, if specified there will be no returned Figure since it is redundant. Returns: matplotlib.Figure: The matplotlib.Figure of the visualization if neither ax_real or ax_imag is set. Raises: MissingOptionalLibraryError: Requires matplotlib. VisualizationError: if input is not a valid N-qubit state. Example: .. jupyter-execute:: from qiskit import QuantumCircuit from qiskit.quantum_info import DensityMatrix from qiskit.visualization import plot_state_hinton %matplotlib inline qc = QuantumCircuit(2) qc.h(0) qc.cx(0, 1) state = DensityMatrix.from_instruction(qc) plot_state_hinton(state, title="New Hinton Plot") """ if not HAS_MATPLOTLIB: raise MissingOptionalLibraryError( libname="Matplotlib", name="plot_state_hinton", pip_install="pip install matplotlib", ) from matplotlib import pyplot as plt # Figure data rho = DensityMatrix(state) num = rho.num_qubits if num is None: raise VisualizationError("Input is not a multi-qubit quantum state.") max_weight = 2 ** np.ceil(np.log(np.abs(rho.data).max()) / np.log(2)) datareal = np.real(rho.data) dataimag = np.imag(rho.data) if figsize is None: figsize = (8, 5) if not ax_real and not ax_imag: fig, (ax1, ax2) = plt.subplots(1, 2, figsize=figsize) else: if ax_real: fig = ax_real.get_figure() else: fig = ax_imag.get_figure() ax1 = ax_real ax2 = ax_imag column_names = [bin(i)[2:].zfill(num) for i in range(2 ** num)] row_names = [bin(i)[2:].zfill(num) for i in range(2 ** num)] ly, lx = datareal.shape # Real if ax1: ax1.patch.set_facecolor("gray") ax1.set_aspect("equal", "box") ax1.xaxis.set_major_locator(plt.NullLocator()) ax1.yaxis.set_major_locator(plt.NullLocator()) for (x, y), w in np.ndenumerate(datareal): color = "white" if w > 0 else "black" size = np.sqrt(np.abs(w) / max_weight) rect = plt.Rectangle( [0.5 + x - size / 2, 0.5 + y - size / 2], size, size, facecolor=color, edgecolor=color, ) ax1.add_patch(rect) ax1.set_xticks(0.5 + np.arange(lx)) ax1.set_yticks(0.5 + np.arange(ly)) ax1.set_xlim([0, lx]) ax1.set_ylim([ly, 0]) ax1.set_yticklabels(row_names, fontsize=14) ax1.set_xticklabels(column_names, fontsize=14, rotation=90) ax1.invert_yaxis() ax1.set_title("Re[$\\rho$]", fontsize=14) # Imaginary if ax2: ax2.patch.set_facecolor("gray") ax2.set_aspect("equal", "box") ax2.xaxis.set_major_locator(plt.NullLocator()) ax2.yaxis.set_major_locator(plt.NullLocator()) for (x, y), w in np.ndenumerate(dataimag): color = "white" if w > 0 else "black" size = np.sqrt(np.abs(w) / max_weight) rect = plt.Rectangle( [0.5 + x - size / 2, 0.5 + y - size / 2], size, size, facecolor=color, edgecolor=color, ) ax2.add_patch(rect) ax2.set_xticks(0.5 + np.arange(lx)) ax2.set_yticks(0.5 + np.arange(ly)) ax1.set_xlim([0, lx]) ax1.set_ylim([ly, 0]) ax2.set_yticklabels(row_names, fontsize=14) ax2.set_xticklabels(column_names, fontsize=14, rotation=90) ax2.invert_yaxis() ax2.set_title("Im[$\\rho$]", fontsize=14) if title: fig.suptitle(title, fontsize=16) if ax_real is None and ax_imag is None: matplotlib_close_if_inline(fig) if filename is None: return fig else: return fig.savefig(filename)
def plot_state_city( state, title="", figsize=None, color=None, alpha=1, ax_real=None, ax_imag=None, *, rho=None, filename=None, ): """Plot the cityscape of quantum state. Plot two 3d bar graphs (two dimensional) of the real and imaginary part of the density matrix rho. Args: state (Statevector or DensityMatrix or ndarray): an N-qubit quantum state. title (str): a string that represents the plot title figsize (tuple): Figure size in inches. color (list): A list of len=2 giving colors for real and imaginary components of matrix elements. alpha (float): Transparency value for bars ax_real (matplotlib.axes.Axes): An optional Axes object to be used for the visualization output. If none is specified a new matplotlib Figure will be created and used. If this is specified without an ax_imag only the real component plot will be generated. Additionally, if specified there will be no returned Figure since it is redundant. ax_imag (matplotlib.axes.Axes): An optional Axes object to be used for the visualization output. If none is specified a new matplotlib Figure will be created and used. If this is specified without an ax_real only the imaginary component plot will be generated. Additionally, if specified there will be no returned Figure since it is redundant. Returns: matplotlib.Figure: The matplotlib.Figure of the visualization if the ``ax_real`` and ``ax_imag`` kwargs are not set Raises: MissingOptionalLibraryError: Requires matplotlib. ValueError: When 'color' is not a list of len=2. VisualizationError: if input is not a valid N-qubit state. Example: .. jupyter-execute:: from qiskit import QuantumCircuit from qiskit.quantum_info import DensityMatrix from qiskit.visualization import plot_state_city %matplotlib inline qc = QuantumCircuit(2) qc.h(0) qc.cx(0, 1) state = DensityMatrix.from_instruction(qc) plot_state_city(state, color=['midnightblue', 'midnightblue'], title="New State City") """ if not HAS_MATPLOTLIB: raise MissingOptionalLibraryError( libname="Matplotlib", name="plot_state_city", pip_install="pip install matplotlib", ) from matplotlib import pyplot as plt from mpl_toolkits.mplot3d.art3d import Poly3DCollection rho = DensityMatrix(state) num = rho.num_qubits if num is None: raise VisualizationError("Input is not a multi-qubit quantum state.") # get the real and imag parts of rho datareal = np.real(rho.data) dataimag = np.imag(rho.data) # get the labels column_names = [bin(i)[2:].zfill(num) for i in range(2 ** num)] row_names = [bin(i)[2:].zfill(num) for i in range(2 ** num)] lx = len(datareal[0]) # Work out matrix dimensions ly = len(datareal[:, 0]) xpos = np.arange(0, lx, 1) # Set up a mesh of positions ypos = np.arange(0, ly, 1) xpos, ypos = np.meshgrid(xpos + 0.25, ypos + 0.25) xpos = xpos.flatten() ypos = ypos.flatten() zpos = np.zeros(lx * ly) dx = 0.5 * np.ones_like(zpos) # width of bars dy = dx.copy() dzr = datareal.flatten() dzi = dataimag.flatten() if color is None: color = ["#648fff", "#648fff"] else: if len(color) != 2: raise ValueError("'color' must be a list of len=2.") if color[0] is None: color[0] = "#648fff" if color[1] is None: color[1] = "#648fff" if ax_real is None and ax_imag is None: # set default figure size if figsize is None: figsize = (15, 5) fig = plt.figure(figsize=figsize) ax1 = fig.add_subplot(1, 2, 1, projection="3d") ax2 = fig.add_subplot(1, 2, 2, projection="3d") elif ax_real is not None: fig = ax_real.get_figure() ax1 = ax_real ax2 = ax_imag else: fig = ax_imag.get_figure() ax1 = None ax2 = ax_imag max_dzr = max(dzr) min_dzr = min(dzr) min_dzi = np.min(dzi) max_dzi = np.max(dzi) if ax1 is not None: fc1 = generate_facecolors(xpos, ypos, zpos, dx, dy, dzr, color[0]) for idx, cur_zpos in enumerate(zpos): if dzr[idx] > 0: zorder = 2 else: zorder = 0 b1 = ax1.bar3d( xpos[idx], ypos[idx], cur_zpos, dx[idx], dy[idx], dzr[idx], alpha=alpha, zorder=zorder, ) b1.set_facecolors(fc1[6 * idx : 6 * idx + 6]) xlim, ylim = ax1.get_xlim(), ax1.get_ylim() x = [xlim[0], xlim[1], xlim[1], xlim[0]] y = [ylim[0], ylim[0], ylim[1], ylim[1]] z = [0, 0, 0, 0] verts = [list(zip(x, y, z))] pc1 = Poly3DCollection(verts, alpha=0.15, facecolor="k", linewidths=1, zorder=1) if min(dzr) < 0 < max(dzr): ax1.add_collection3d(pc1) ax1.set_xticks(np.arange(0.5, lx + 0.5, 1)) ax1.set_yticks(np.arange(0.5, ly + 0.5, 1)) if max_dzr != min_dzr: ax1.axes.set_zlim3d(np.min(dzr), max(np.max(dzr) + 1e-9, max_dzi)) else: if min_dzr == 0: ax1.axes.set_zlim3d(np.min(dzr), max(np.max(dzr) + 1e-9, np.max(dzi))) else: ax1.axes.set_zlim3d(auto=True) ax1.get_autoscalez_on() ax1.w_xaxis.set_ticklabels(row_names, fontsize=14, rotation=45, ha="right", va="top") ax1.w_yaxis.set_ticklabels( column_names, fontsize=14, rotation=-22.5, ha="left", va="center" ) ax1.set_zlabel("Re[$\\rho$]", fontsize=14) for tick in ax1.zaxis.get_major_ticks(): tick.label.set_fontsize(14) if ax2 is not None: fc2 = generate_facecolors(xpos, ypos, zpos, dx, dy, dzi, color[1]) for idx, cur_zpos in enumerate(zpos): if dzi[idx] > 0: zorder = 2 else: zorder = 0 b2 = ax2.bar3d( xpos[idx], ypos[idx], cur_zpos, dx[idx], dy[idx], dzi[idx], alpha=alpha, zorder=zorder, ) b2.set_facecolors(fc2[6 * idx : 6 * idx + 6]) xlim, ylim = ax2.get_xlim(), ax2.get_ylim() x = [xlim[0], xlim[1], xlim[1], xlim[0]] y = [ylim[0], ylim[0], ylim[1], ylim[1]] z = [0, 0, 0, 0] verts = [list(zip(x, y, z))] pc2 = Poly3DCollection(verts, alpha=0.2, facecolor="k", linewidths=1, zorder=1) if min(dzi) < 0 < max(dzi): ax2.add_collection3d(pc2) ax2.set_xticks(np.arange(0.5, lx + 0.5, 1)) ax2.set_yticks(np.arange(0.5, ly + 0.5, 1)) if min_dzi != max_dzi: eps = 0 ax2.axes.set_zlim3d(np.min(dzi), max(np.max(dzr) + 1e-9, np.max(dzi) + eps)) else: if min_dzi == 0: ax2.set_zticks([0]) eps = 1e-9 ax2.axes.set_zlim3d(np.min(dzi), max(np.max(dzr) + 1e-9, np.max(dzi) + eps)) else: ax2.axes.set_zlim3d(auto=True) ax2.w_xaxis.set_ticklabels(row_names, fontsize=14, rotation=45, ha="right", va="top") ax2.w_yaxis.set_ticklabels( column_names, fontsize=14, rotation=-22.5, ha="left", va="center" ) ax2.set_zlabel("Im[$\\rho$]", fontsize=14) for tick in ax2.zaxis.get_major_ticks(): tick.label.set_fontsize(14) ax2.get_autoscalez_on() fig.suptitle(title, fontsize=16) if ax_real is None and ax_imag is None: matplotlib_close_if_inline(fig) if filename is None: return fig else: return fig.savefig(filename)
def plot_bloch_multivector( state, title="", figsize=None, *, rho=None, reverse_bits=False, filename=None ): """Plot the Bloch sphere. Plot a sphere, axes, the Bloch vector, and its projections onto each axis. Args: state (Statevector or DensityMatrix or ndarray): an N-qubit quantum state. title (str): a string that represents the plot title figsize (tuple): Has no effect, here for compatibility only. reverse_bits (bool): If True, plots qubits following Qiskit's convention [Default:False]. Returns: matplotlib.Figure: A matplotlib figure instance. Raises: MissingOptionalLibraryError: Requires matplotlib. VisualizationError: if input is not a valid N-qubit state. Example: .. jupyter-execute:: from qiskit import QuantumCircuit from qiskit.quantum_info import Statevector from qiskit.visualization import plot_bloch_multivector %matplotlib inline qc = QuantumCircuit(2) qc.h(0) qc.cx(0, 1) state = Statevector.from_instruction(qc) plot_bloch_multivector(state, title="New Bloch Multivector", reverse_bits=False) """ if not HAS_MATPLOTLIB: raise MissingOptionalLibraryError( libname="Matplotlib", name="plot_bloch_multivector", pip_install="pip install matplotlib", ) from matplotlib import pyplot as plt # Data bloch_data = ( _bloch_multivector_data(state)[::-1] if reverse_bits else _bloch_multivector_data(state) ) num = len(bloch_data) width, height = plt.figaspect(1 / num) fig = plt.figure(figsize=(width, height)) for i in range(num): pos = num - 1 - i if reverse_bits else i ax = fig.add_subplot(1, num, i + 1, projection="3d") plot_bloch_vector(bloch_data[i], "qubit " + str(pos), ax=ax, figsize=figsize) fig.suptitle(title, fontsize=16, y=1.01) matplotlib_close_if_inline(fig) if filename is None: return fig else: return fig.savefig(filename)
def pulse_drawer( data: Union[Waveform, Union[Schedule, Instruction]], dt: int = 1, style: Union[PulseStyle, SchedStyle] = None, filename: str = None, interp_method: Callable = None, scale: float = None, channel_scales: Dict[Channel, float] = None, plot_all: bool = False, plot_range: Tuple[float, float] = None, interactive: bool = False, table: bool = False, label: bool = False, framechange: bool = True, channels: List[Channel] = None, show_framechange_channels: bool = True, draw_title: bool = False, ): """Deprecated. Plot the interpolated envelope of pulse and schedule. Args: data: Pulse or schedule object to plot. dt: Time interval of samples. Pulses are visualized in the unit of cycle time if not provided. style: A style sheet to configure plot appearance. See :mod:`~qiskit.visualization.pulse.qcstyle` for more information. filename: Name required to save pulse image. The drawer just returns `matplot.Figure` object if not provided. interp_method: Interpolation function. Interpolation is disabled in default. See :mod:`~qiskit.visualization.pulse.interpolation` for more information. scale: Scaling of waveform amplitude. Pulses are automatically scaled channel by channel if not provided. channel_scales: Dictionary of scale factor for specific channels. Scale of channels not specified here is overwritten by `scale`. plot_all: When set `True` plot empty channels. plot_range: A tuple of time range to plot. interactive: When set `True` show the circuit in a new window. This depends on the matplotlib backend being used supporting this. table: When set `True` draw event table for supported commands. label: When set `True` draw label for individual instructions. framechange: When set `True` draw framechange indicators. channels: A list of channel names to plot. All non-empty channels are shown if not provided. show_framechange_channels: When set `True` plot channels with only framechange instructions. draw_title: Add a title to the plot when set to ``True``. Returns: matplotlib.figure.Figure: A matplotlib figure object for the pulse envelope. Example: This example shows how to visualize your pulse schedule. Pulse names are added to the plot, unimportant channels are removed and the time window is truncated to draw out U3 pulse sequence of interest. .. jupyter-execute:: import numpy as np import qiskit from qiskit import pulse from qiskit.providers.fake_provider import FakeAlmaden inst_map = FakeAlmaden().defaults().instruction_schedule_map sched = pulse.Schedule() sched += inst_map.get('u3', 0, np.pi, 0, np.pi) sched += inst_map.get('measure', list(range(20))) << sched.duration channels = [pulse.DriveChannel(0), pulse.MeasureChannel(0)] scales = {pulse.DriveChannel(0): 10} qiskit.visualization.pulse_drawer(sched, channels=channels, plot_range=(0, 1000), label=True, channel_scales=scales) You are also able to call visualization module from the instance method:: sched.draw(channels=channels, plot_range=(0, 1000), label=True, channel_scales=scales) To customize the format of the schedule plot, you can setup your style sheet. .. jupyter-execute:: import numpy as np import qiskit from qiskit import pulse from qiskit.providers.fake_provider import FakeAlmaden inst_map = FakeAlmaden().defaults().instruction_schedule_map sched = pulse.Schedule() sched += inst_map.get('u3', 0, np.pi, 0, np.pi) sched += inst_map.get('measure', list(range(20))) << sched.duration # setup style sheet my_style = qiskit.visualization.SchedStyle( figsize = (10, 5), bg_color='w', d_ch_color = ['#32cd32', '#556b2f']) channels = [pulse.DriveChannel(0), pulse.MeasureChannel(0)] scales = {pulse.DriveChannel(0): 10} qiskit.visualization.pulse_drawer(sched, style=my_style, channels=channels, plot_range=(0, 1000), label=True, channel_scales=scales) Raises: VisualizationError: when invalid data is given MissingOptionalLibraryError: when matplotlib is not installed """ warnings.warn( "This legacy pulse drawer is deprecated and will be removed no earlier than " "3 months after the release date. Use `qiskit.visualization.pulse_drawer_v2` " "instead. After the legacy drawer is removed, the import path of this module " "will be dedicated to the v2 drawer. " "New drawer will provide much more flexibility with richer stylesheets " "and cleaner visualization.", DeprecationWarning, ) if isinstance(data, Waveform): drawer = _matplotlib.WaveformDrawer(style=style) image = drawer.draw(data, dt=dt, interp_method=interp_method, scale=scale) elif isinstance(data, (Schedule, Instruction)): drawer = _matplotlib.ScheduleDrawer(style=style) image = drawer.draw( data, dt=dt, interp_method=interp_method, scale=scale, channel_scales=channel_scales, plot_range=plot_range, plot_all=plot_all, table=table, label=label, framechange=framechange, channels=channels, show_framechange_channels=show_framechange_channels, draw_title=draw_title, ) else: raise VisualizationError("This data cannot be visualized.") if filename: image.savefig(filename, dpi=drawer.style.dpi, bbox_inches="tight") matplotlib_close_if_inline(image) if image and interactive: image.show() return image