<pl-question-panel>
<p>This question was created to show the graph rendering capabilities of the <a href="https://docs.prairielearn.com/elements/pl-graph"><code>pl-graph</code></a> element.</p>
</pl-question-panel>
<pl-card>
<pl-question-panel>
<p>Here's a static graph that was created by hand with DOT markup:</p>
<pl-code language="html">
<pl-graph>
digraph G {
A -> B
B -> C
}
</pl-graph>
</pl-code>
</pl-question-panel>
<pl-graph>
digraph G {
A -> B
B -> C
}
</pl-graph>
</pl-card>
<pl-card>
<pl-question-panel>
<p>Here's a graph with randomly-generated edge weights. Because here the graph is specified in the <code>question.html</code>, parameters can be templated using Mustache.</p>
<pl-code language="html">
<pl-graph>
digraph G {
A -> B [label="{{ params.weight1 }}"]
B -> C [label="{{ params.weight2 }}"]
}
</pl-graph>
</pl-code>
</pl-question-panel>
<pl-graph>
digraph G {
A -> B [label=" {{ params.weight1 }}"]
B -> C [label=" {{ params.weight2 }}"]
}
</pl-graph>
</pl-card>
<pl-card>
<pl-question-panel>
<p>Here's a graph created from a randomly-generated adjacency matrix. By default, weights will be displayed when they are not <code>0</code> or <code>1</code>. The matrix and labels can be specified with <code>params-name</code> and <code>params-name-labels</code>, respectively.</p>
<pl-code language="python">
mat = np.random.random((3, 3))
mat = mat / la.norm(mat, 1, axis=0)
data['params']['labels'] = pl.to_json(['A', 'B', 'C'])
data['params']['matrix'] = pl.to_json(mat)
</pl-code>
<pl-code language="html">
<pl-matrix-latex params-name="matrix"></pl-matrix-latex>
<pl-graph params-name="matrix" params-name-labels="labels"></pl-graph>
</pl-code>
</pl-question-panel>
<pl-matrix-latex params-name="matrix"></pl-matrix-latex>
<pl-graph params-name="matrix" params-name-labels="labels"></pl-graph>
</pl-card>
<pl-card>
<pl-question-panel>
<p>To force no weights being displayed, the attribute <code>weights</code> can be set to <code>"false"</code>. Here is the same graph with no edge weights.</p>
</pl-question-panel>
<pl-graph params-name="matrix" params-name-labels="labels" weights="false"></pl-graph>
</pl-card>
<pl-card>
<pl-question-panel>
<p>To force the graph to be undirected, the attribute <code>directed</code> can be set to <code>"false"</code>. Here is an undirected graph.
<b>The input matrix must be symmetric in this case.</b>
</p>
</pl-question-panel>
<pl-matrix-latex params-name="symmetric_matrix"></pl-matrix-latex>
<pl-graph params-name="symmetric_matrix" params-name-labels="labels" directed="false"></pl-graph>
</pl-card>
<pl-card>
<pl-question-panel>
<p>The formatting of the weight labels can also be changed with the <code>weights-digits</code> and <code>weights-presentation-type</code> attributes. This example has <code>weights-digits="5"</code>.</p>
</pl-question-panel>
<pl-graph params-name="matrix" params-name-labels="labels" weights-digits="5"></pl-graph>
</pl-card>
<pl-card>
<pl-question-panel>
<p>Here is another graph with binary <code>0</code> or <code>1</code> weights. These weights will not be displayed unless specified with <code>weights="true"</code>.</p>
</pl-question-panel>
<pl-matrix-latex params-name="matrix2"></pl-matrix-latex>
<pl-graph params-name="matrix2"></pl-graph>
</pl-card>
<pl-card>
<pl-question-panel>
<p>Here is a graph with negative weights. These weights will not be displayed unless specified with
<code>negative-weights="true"</code>.
In the input matrix, to hide an edge, simply set the corresponding entry to <code>None</code>.
</p>
</pl-question-panel>
<pl-python-variable params-name="matrix3"></pl-python-variable>
<pl-graph params-name="matrix3" params-name-labels="labels" negative-weights="true"></pl-graph>
</pl-card>
<pl-card>
<pl-question-panel>
<p> The <code>pl-graph</code> element has the ability to be extended on a course level to create graphs based on custom inputs. This course extension located in <code>elementExtensions/pl-graph/edge-inc-matrix</code> adds the capability of rendering edge-incidence matrices as graphs. </p>
<pl-matrix-latex params-name="edge-inc-mat"></pl-matrix-latex>
<pl-graph params-name="edge-inc-mat" params-type="edge-inc-matrix"></pl-graph>
<p> For more information on how to create extensions, check the <a href="https://docs.prairielearn.com/elementExtensions">extension documentation</a> and <a href="https://docs.prairielearn.com/elements/pl-graph">graph element documentation</a>. </p>
</pl-question-panel>
</pl-card>
<pl-card>
<pl-question-panel>
<p>Here's a graph created from a randomly-generated networkx graph.
To specify the use of a networkx graph, set <code>params-type="networkx"</code>.
The graph can be specified with <code>params-name</code>.
To make it accessible to screen readers, set <code>aria-label</code> to a description of the graph; since a static label can't describe a randomly-generated graph, that description is generated in <code>server.py</code> from the graph data.
</p>
<pl-code language="python">
random_graph = nx.gnm_random_graph(5, 6)
for in_node, out_node, edge_data in random_graph.edges(data=True):
edge_data['label'] = random.choice(string.ascii_lowercase)
data['params']['random-graph'] = pl.to_json(random_graph)
edges = ", ".join(
f"{in_node} to {out_node} (labeled {edge_data['label']})"
for in_node, out_node, edge_data in random_graph.edges(data=True)
)
data['params']['random_graph_alt'] = (
f"Undirected graph with {random_graph.number_of_nodes()} nodes "
f"and {random_graph.number_of_edges()} edges: {edges}."
)
</pl-code>
<pl-code language="html">
<pl-graph params-type="networkx" params-name="random-graph" aria-label="{{ params.random_graph_alt }}"></pl-graph>
</pl-code>
</pl-question-panel>
<pl-graph params-type="networkx" params-name="random-graph" aria-label="{{ params.random_graph_alt }}"></pl-graph>
</pl-card>
<pl-card>
<pl-question-panel>
<p>Rendering directed graphs and multigraphs is supported natively with networkx.
Here, we also set <code>rankdir="LR"</code> in the constructor for the graph.
</p>
</pl-question-panel>
<pl-graph params-type="networkx" params-name="multigraph"></pl-graph>
</pl-card>
<pl-card>
<pl-question-panel>
<p>The color of each node or edge in a networkx graph can be set by assigning the <code>'color'</code> attribute in the
associated data dictionary for each object. In the example below, we've set the color of each edge to <code>'blue'</code>
and used different colors for nodes in different layers.
</p>
</pl-question-panel>
<pl-graph params-type="networkx" params-name="color-graph"></pl-graph>
</pl-card>
<pl-card>
<pl-question-panel>
<p>The <code>source-file-name</code> attribute allows loading graph content from an external file. This is particularly useful for graphs with complex DOT syntax, such as record-based nodes that use angle brackets <code><></code>, which can cause issues when embedded directly in HTML.</p>
<pl-code language="html">
<pl-graph source-file-name="record-graph.dot"></pl-graph>
</pl-code>
<p>The file <code>record-graph.dot</code> contains:</p>
<pl-code language="graphviz" source-file-name="record-graph.dot"></pl-code>
</pl-question-panel>
<pl-graph source-file-name="record-graph.dot"></pl-graph>
</pl-card>