def test_graph_with_removed_nodes(self): graph = retworkx.PyGraph() nodes = graph.add_nodes_from([0, 1, 2]) graph.remove_node(nodes[1]) res = retworkx.spring_layout(graph) self.assertEqual(len(res), 2) self.assertTrue(nodes[0] in res) self.assertTrue(nodes[2] in res) self.assertFalse(nodes[1] in res)
def draw_graph(graph, pos=None, arrows=True, with_labels=False, **kwds): r"""Draw the graph using Matplotlib. Draw the graph with Matplotlib with options for node positions, labeling, titles, and many other drawing features. See draw() for simple drawing without labels or axes. Parameters ---------- graph: A retworkx :class:`~retworkx.PyDiGraph` or :class:`~retworkx.PyGraph` pos : dictionary, optional A dictionary with nodes as keys and positions as values. If not specified a spring layout positioning will be computed. See :mod:`retworkx.drawing.layout` for functions that compute node positions. Notes ----- For directed graphs, arrows are drawn at the head end. Arrows can be turned off with keyword arrows=False. """ try: import matplotlib.pyplot as plt except ImportError as e: raise ImportError("matplotlib needs to be installed prior to running " "retworkx.visualization.mpl_draw(). You can install " "matplotlib with:\n'pip install matplotlib'") from e valid_node_kwds = { "node_list", "node_size", "node_color", "node_shape", "alpha", "cmap", "vmin", "vmax", "ax", "linewidths", "edgecolors", "label", } valid_edge_kwds = { "edge_list", "width", "edge_color", "style", "alpha", "arrowstyle", "arrow_size", "edge_cmap", "edge_vmin", "edge_vmax", "ax", "label", "node_size", "node_list", "node_shape", "connectionstyle", "min_source_margin", "min_target_margin", } valid_label_kwds = { "labels", "font_size", "font_color", "font_family", "font_weight", "alpha", "bbox", "ax", "horizontalalignment", "verticalalignment", } valid_edge_label_kwds = { "edge_labels", "font_size", "font_color", "font_family", "font_weight", "alpha", "bbox", "ax", "rotate", "horizontalalignment", "verticalalignment", } valid_kwds = (valid_node_kwds | valid_edge_kwds | valid_label_kwds | valid_edge_label_kwds) if any([k not in valid_kwds for k in kwds]): invalid_args = ", ".join([k for k in kwds if k not in valid_kwds]) raise ValueError(f"Received invalid argument(s): {invalid_args}") label_fn = kwds.pop("labels", None) if label_fn: kwds["labels"] = {x: label_fn(graph[x]) for x in graph.node_indexes()} edge_label_fn = kwds.pop("edge_labels", None) if edge_label_fn: kwds["edge_labels"] = {(x[0], x[1]): edge_label_fn(x[2]) for x in graph.weighted_edge_list()} node_kwds = {k: v for k, v in kwds.items() if k in valid_node_kwds} edge_kwds = {k: v for k, v in kwds.items() if k in valid_edge_kwds} if isinstance(edge_kwds.get("alpha"), list): del edge_kwds["alpha"] label_kwds = {k: v for k, v in kwds.items() if k in valid_label_kwds} edge_label_kwds = { k: v for k, v in kwds.items() if k in valid_edge_label_kwds } if pos is None: pos = retworkx.spring_layout(graph) # default to spring layout draw_nodes(graph, pos, **node_kwds) draw_edges(graph, pos, arrows=arrows, **edge_kwds) if with_labels: draw_labels(graph, pos, **label_kwds) if edge_label_fn: draw_edge_labels(graph, pos, **edge_label_kwds) plt.draw_if_interactive()
def plot_gate_map( backend, figsize=None, plot_directed=False, label_qubits=True, qubit_size=None, line_width=4, font_size=None, qubit_color=None, qubit_labels=None, line_color=None, font_color="w", ax=None, filename=None, qubit_coordinates=None, ): """Plots the gate map of a device. Args: backend (Backend): The backend instance that will be used to plot the device gate map. figsize (tuple): Output figure size (wxh) in inches. plot_directed (bool): Plot directed coupling map. label_qubits (bool): Label the qubits. qubit_size (float): Size of qubit marker. line_width (float): Width of lines. font_size (int): Font size of qubit labels. qubit_color (list): A list of colors for the qubits qubit_labels (list): A list of qubit labels line_color (list): A list of colors for each line from coupling_map. font_color (str): The font color for the qubit labels. ax (Axes): A Matplotlib axes instance. filename (str): file path to save image to. qubit_coordinates (Sequence): An optional sequence input (list or array being the most common) of 2d coordinates for each qubit. The length of the sequence much match the number of qubits on the backend. The sequence should be the planar coordinates in a 0-based square grid where each qubit is located. Returns: Figure: A Matplotlib figure instance. Raises: QiskitError: if tried to pass a simulator, or if the backend is None, but one of num_qubits, mpl_data, or cmap is None. MissingOptionalLibraryError: if matplotlib not installed. Example: .. jupyter-execute:: :hide-code: :hide-output: from qiskit.test.ibmq_mock import mock_get_backend mock_get_backend('FakeVigo') .. jupyter-execute:: from qiskit import QuantumCircuit, execute, IBMQ from qiskit.visualization import plot_gate_map %matplotlib inline provider = IBMQ.load_account() accountProvider = IBMQ.get_provider(hub='ibm-q') backend = accountProvider.get_backend('ibmq_vigo') plot_gate_map(backend) """ qubit_coordinates_map = {} qubit_coordinates_map[1] = [[0, 0]] qubit_coordinates_map[5] = [[1, 0], [0, 1], [1, 1], [1, 2], [2, 1]] qubit_coordinates_map[7] = [[0, 0], [0, 1], [0, 2], [1, 1], [2, 0], [2, 1], [2, 2]] qubit_coordinates_map[20] = [ [0, 0], [0, 1], [0, 2], [0, 3], [0, 4], [1, 0], [1, 1], [1, 2], [1, 3], [1, 4], [2, 0], [2, 1], [2, 2], [2, 3], [2, 4], [3, 0], [3, 1], [3, 2], [3, 3], [3, 4], ] qubit_coordinates_map[15] = [ [0, 0], [0, 1], [0, 2], [0, 3], [0, 4], [0, 5], [0, 6], [1, 7], [1, 6], [1, 5], [1, 4], [1, 3], [1, 2], [1, 1], [1, 0], ] qubit_coordinates_map[16] = [ [1, 0], [1, 1], [2, 1], [3, 1], [1, 2], [3, 2], [0, 3], [1, 3], [3, 3], [4, 3], [1, 4], [3, 4], [1, 5], [2, 5], [3, 5], [1, 6], ] qubit_coordinates_map[27] = [ [1, 0], [1, 1], [2, 1], [3, 1], [1, 2], [3, 2], [0, 3], [1, 3], [3, 3], [4, 3], [1, 4], [3, 4], [1, 5], [2, 5], [3, 5], [1, 6], [3, 6], [0, 7], [1, 7], [3, 7], [4, 7], [1, 8], [3, 8], [1, 9], [2, 9], [3, 9], [3, 10], ] qubit_coordinates_map[28] = [ [0, 2], [0, 3], [0, 4], [0, 5], [0, 6], [1, 2], [1, 6], [2, 0], [2, 1], [2, 2], [2, 3], [2, 4], [2, 5], [2, 6], [2, 7], [2, 8], [3, 0], [3, 4], [3, 8], [4, 0], [4, 1], [4, 2], [4, 3], [4, 4], [4, 5], [4, 6], [4, 7], [4, 8], ] qubit_coordinates_map[53] = [ [0, 2], [0, 3], [0, 4], [0, 5], [0, 6], [1, 2], [1, 6], [2, 0], [2, 1], [2, 2], [2, 3], [2, 4], [2, 5], [2, 6], [2, 7], [2, 8], [3, 0], [3, 4], [3, 8], [4, 0], [4, 1], [4, 2], [4, 3], [4, 4], [4, 5], [4, 6], [4, 7], [4, 8], [5, 2], [5, 6], [6, 0], [6, 1], [6, 2], [6, 3], [6, 4], [6, 5], [6, 6], [6, 7], [6, 8], [7, 0], [7, 4], [7, 8], [8, 0], [8, 1], [8, 2], [8, 3], [8, 4], [8, 5], [8, 6], [8, 7], [8, 8], [9, 2], [9, 6], ] qubit_coordinates_map[65] = [ [0, 0], [0, 1], [0, 2], [0, 3], [0, 4], [0, 5], [0, 6], [0, 7], [0, 8], [0, 9], [1, 0], [1, 4], [1, 8], [2, 0], [2, 1], [2, 2], [2, 3], [2, 4], [2, 5], [2, 6], [2, 7], [2, 8], [2, 9], [2, 10], [3, 2], [3, 6], [3, 10], [4, 0], [4, 1], [4, 2], [4, 3], [4, 4], [4, 5], [4, 6], [4, 7], [4, 8], [4, 9], [4, 10], [5, 0], [5, 4], [5, 8], [6, 0], [6, 1], [6, 2], [6, 3], [6, 4], [6, 5], [6, 6], [6, 7], [6, 8], [6, 9], [6, 10], [7, 2], [7, 6], [7, 10], [8, 1], [8, 2], [8, 3], [8, 4], [8, 5], [8, 6], [8, 7], [8, 8], [8, 9], [8, 10], ] qubit_coordinates_map[127] = [ [0, 0], [0, 1], [0, 2], [0, 3], [0, 4], [0, 5], [0, 6], [0, 7], [0, 8], [0, 9], [0, 10], [0, 11], [0, 12], [0, 13], [1, 0], [1, 4], [1, 8], [1, 12], [2, 0], [2, 1], [2, 2], [2, 3], [2, 4], [2, 5], [2, 6], [2, 7], [2, 8], [2, 9], [2, 10], [2, 11], [2, 12], [2, 13], [2, 14], [3, 2], [3, 6], [3, 10], [3, 14], [4, 0], [4, 1], [4, 2], [4, 3], [4, 4], [4, 5], [4, 6], [4, 7], [4, 8], [4, 9], [4, 10], [4, 11], [4, 12], [4, 13], [4, 14], [5, 0], [5, 4], [5, 8], [5, 12], [6, 0], [6, 1], [6, 2], [6, 3], [6, 4], [6, 5], [6, 6], [6, 7], [6, 8], [6, 9], [6, 10], [6, 11], [6, 12], [6, 13], [6, 14], [7, 2], [7, 6], [7, 10], [7, 14], [8, 0], [8, 1], [8, 2], [8, 3], [8, 4], [8, 5], [8, 6], [8, 7], [8, 8], [8, 9], [8, 10], [8, 11], [8, 12], [8, 13], [8, 14], [9, 0], [9, 4], [9, 8], [9, 12], [10, 0], [10, 1], [10, 2], [10, 3], [10, 4], [10, 5], [10, 6], [10, 7], [10, 8], [10, 9], [10, 10], [10, 11], [10, 12], [10, 13], [10, 14], [11, 2], [11, 6], [11, 10], [11, 14], [12, 1], [12, 2], [12, 3], [12, 4], [12, 5], [12, 6], [12, 7], [12, 8], [12, 9], [12, 10], [12, 11], [12, 12], [12, 13], [12, 14], ] backend_version = _get_backend_interface_version(backend) if backend_version <= 1: from qiskit.transpiler.coupling import CouplingMap if backend.configuration().simulator: raise QiskitError("Requires a device backend, not simulator.") config = backend.configuration() num_qubits = config.n_qubits coupling_map = CouplingMap(config.coupling_map) name = backend.name() else: num_qubits = backend.num_qubits coupling_map = backend.coupling_map name = backend.name if qubit_coordinates is None and ("ibm" in name or "fake" in name): qubit_coordinates = qubit_coordinates_map.get(num_qubits, None) if qubit_coordinates is None: # Replace with planar_layout() when retworkx offers it qubit_coordinates_rx = rx.spring_layout(coupling_map.graph, seed=1234) scaling_factor = 10**int(math.log10(num_qubits) + 1) qubit_coordinates = [( int(scaling_factor * qubit_coordinates_rx[i][0]), int(scaling_factor * qubit_coordinates_rx[i][1]), ) for i in range(num_qubits)] if any(x[0] < 0 or x[1] < 0 for x in qubit_coordinates): min_entry = min(qubit_coordinates, key=lambda x: min(x[0], x[1])) negative_offset = 0 - min(min_entry) qubit_coordinates = [(x[0] + negative_offset, x[1] + negative_offset) for x in qubit_coordinates] if len(qubit_coordinates) != num_qubits: raise QiskitError( f"The number of specified qubit coordinates {len(qubit_coordinates)} " f"does not match the device number of qubits: {num_qubits}") return plot_coupling_map( num_qubits, qubit_coordinates, coupling_map.get_edges(), figsize, plot_directed, label_qubits, qubit_size, line_width, font_size, qubit_color, qubit_labels, line_color, font_color, ax, filename, )
def test_simple_graph_fixed_not_pos(self): with self.assertRaises(ValueError): retworkx.spring_layout(self.graph, fixed={0})
def test_simple_graph_linear_cooling(self): res = retworkx.spring_layout(self.graph, adaptive_cooling=False) self.assertEqual(len(res), 3) self.assertEqual(len(res[0]), 2) self.assertIsInstance(res[0][0], float)
def test_simple_graph_fixed(self): pos = {0: [0.1, 0.1]} res = retworkx.spring_layout(self.graph, pos=pos, fixed={0}) self.assertEqual(res[0], pos[0])
def test_simple_graph_center(self): res = retworkx.spring_layout(self.graph, center=[0.5, 0.5]) self.assertEqual(len(res), 3) self.assertEqual(len(res[0]), 2) self.assertIsInstance(res[0][0], float)
def test_simple_graph_with_edge_weights(self): res = retworkx.spring_layout(self.graph, weight_fn=lambda e: e) self.assertEqual(len(res), 3) self.assertEqual(len(res[0]), 2) self.assertIsInstance(res[0][0], float)
def test_simple_graph(self): res = retworkx.spring_layout(self.graph, seed=42) self.assertEqual(len(res), 3) self.assertEqual(len(res[0]), 2) self.assertIsInstance(res[0][0], float)
def test_empty_graph(self): graph = retworkx.PyGraph() res = retworkx.spring_layout(graph) self.assertEqual({}, res)