Skip to content

Commit de3d30c

Browse files
committed
fix(notebooks/03-viz)šŸ›: fix code formatting and improve matplotlib integration in visualization notebook
- Update marimo version from 0.13.0 to 0.14.8 for compatibility. - Add hide_code=True to initial app cell for cleaner notebook presentation. - Fix indentation and remove unnecessary r-string markers from markdown cells for better formatting. - Add plt.show() after nx.draw calls to ensure matplotlib figures are displayed. - Remove extra blank lines and trailing whitespace for code cleanliness. - Update markdown content to improve readability and fix minor typos. - Add missing import of plt in relevant cells.
1 parent 44b23c2 commit de3d30c

File tree

1 file changed

+112
-114
lines changed

1 file changed

+112
-114
lines changed

ā€Žnotebooks/01-introduction/03-viz.py

Lines changed: 112 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@
2020

2121
import marimo
2222

23-
__generated_with = "0.13.0"
23+
__generated_with = "0.14.8"
2424
app = marimo.App()
2525

2626

27-
@app.cell
27+
@app.cell(hide_code=True)
2828
def _():
2929
import warnings
3030

@@ -50,18 +50,18 @@ def _():
5050
def _(mo):
5151
mo.md(
5252
r"""
53-
In this chapter, We want to introduce you to the wonderful world of graph visualization.
54-
55-
You probably have seen graphs that are visualized as hairballs.
56-
Apart from communicating how complex the graph is,
57-
hairballs don't really communicate much else.
58-
As such, my goal by the end of this chapter is
59-
to introduce you to what I call _rational graph visualization_.
60-
61-
But before we can do that, let's first make sure we understand
62-
how to use NetworkX's drawing facilities to draw graphs to the screen.
63-
In a pinch, and for small graphs, it's very handy to have.
64-
"""
53+
In this chapter, We want to introduce you to the wonderful world of graph visualization.
54+
55+
You probably have seen graphs that are visualized as hairballs.
56+
Apart from communicating how complex the graph is,
57+
hairballs don't really communicate much else.
58+
As such, my goal by the end of this chapter is
59+
to introduce you to what I call _rational graph visualization_.
60+
61+
But before we can do that, let's first make sure we understand
62+
how to use NetworkX's drawing facilities to draw graphs to the screen.
63+
In a pinch, and for small graphs, it's very handy to have.
64+
"""
6565
)
6666
return
6767

@@ -70,15 +70,15 @@ def _(mo):
7070
def _(mo):
7171
mo.md(
7272
r"""
73-
## Hairballs
73+
## Hairballs
7474
75-
The node-link diagram is the canonical diagram we will see in publications.
76-
Nodes are commonly drawn as circles, while edges are drawn s lines.
75+
The node-link diagram is the canonical diagram we will see in publications.
76+
Nodes are commonly drawn as circles, while edges are drawn s lines.
7777
78-
Node-link diagrams are common,
79-
and there's a good reason for this: it's convenient to draw!
80-
In NetworkX, we can draw node-link diagrams using:
81-
"""
78+
Node-link diagrams are common,
79+
and there's a good reason for this: it's convenient to draw!
80+
In NetworkX, we can draw node-link diagrams using:
81+
"""
8282
)
8383
return
8484

@@ -94,23 +94,24 @@ def _():
9494

9595

9696
@app.cell
97-
def _(G, nx):
97+
def _(G, nx, plt):
9898
nx.draw(G)
99+
plt.show()
99100
return
100101

101102

102103
@app.cell(hide_code=True)
103104
def _(mo):
104105
mo.md(
105106
r"""
106-
Nodes more tightly connected with one another are clustered together.
107-
Initial node placement is done typically at random,
108-
so really it's tough to deterministically generate the same figure.
109-
If the network is small enough to visualize,
110-
and the node labels are small enough to fit in a circle,
111-
then you can use the `with_labels=True` argument
112-
to bring some degree of informativeness to the drawing:
113-
"""
107+
Nodes more tightly connected with one another are clustered together.
108+
Initial node placement is done typically at random,
109+
so really it's tough to deterministically generate the same figure.
110+
If the network is small enough to visualize,
111+
and the node labels are small enough to fit in a circle,
112+
then you can use the `with_labels=True` argument
113+
to bring some degree of informativeness to the drawing:
114+
"""
114115
)
115116
return
116117

@@ -122,28 +123,29 @@ def _(G):
122123

123124

124125
@app.cell
125-
def _(G, nx):
126+
def _(G, nx, plt):
126127
nx.draw(G, with_labels=True)
128+
plt.show()
127129
return
128130

129131

130132
@app.cell(hide_code=True)
131133
def _(mo):
132134
mo.md(
133135
r"""
134-
The downside to drawing graphs this way is that
135-
large graphs end up looking like hairballs.
136-
Can you imagine a graph with more than the 28 nodes that we have?
137-
As you probably can imagine, the default `nx.draw(G)`
138-
is probably not suitable for generating visual insights.
136+
The downside to drawing graphs this way is that
137+
large graphs end up looking like hairballs.
138+
Can you imagine a graph with more than the 28 nodes that we have?
139+
As you probably can imagine, the default `nx.draw(G)`
140+
is probably not suitable for generating visual insights.
139141
140-
## Matrix Plot
142+
## Matrix Plot
141143
142-
A different way that we can visualize a graph is by visualizing it in its matrix form.
143-
The nodes are on the x- and y- axes, and a filled square represent an edge between the nodes.
144+
A different way that we can visualize a graph is by visualizing it in its matrix form.
145+
The nodes are on the x- and y- axes, and a filled square represent an edge between the nodes.
144146
145-
We can draw a graph's matrix form conveniently by using `nxviz.MatrixPlot`:
146-
"""
147+
We can draw a graph's matrix form conveniently by using `nxviz.MatrixPlot`:
148+
"""
147149
)
148150
return
149151

@@ -156,28 +158,27 @@ def _(G, plt):
156158
nv.matrix(G, group_by="gender", node_color_by="gender")
157159
annotate.matrix_group(G, group_by="gender")
158160
plt.show()
159-
160161
return annotate, nv
161162

162163

163164
@app.cell(hide_code=True)
164165
def _(mo):
165166
mo.md(
166167
r"""
167-
What can you tell from the graph visualization?
168-
A few things are immediately obvious:
168+
What can you tell from the graph visualization?
169+
A few things are immediately obvious:
169170
170-
- The diagonal is empty: no student voted for themselves as their favourite.
171-
- The matrix is asymmetric about the diagonal: this is a directed graph!
171+
- The diagonal is empty: no student voted for themselves as their favourite.
172+
- The matrix is asymmetric about the diagonal: this is a directed graph!
172173
173-
(An undirected graph would be symmetric about the diagonal.)
174+
(An undirected graph would be symmetric about the diagonal.)
174175
175-
You might go on to suggest that there is some clustering happening,
176-
but without applying a proper clustering algorithm on the adjacency matrix,
177-
we would be hard-pressed to know for sure.
178-
After all, we can simply re-order the node ordering along the axes
179-
to produce a seemingly-random matrix.
180-
"""
176+
You might go on to suggest that there is some clustering happening,
177+
but without applying a proper clustering algorithm on the adjacency matrix,
178+
we would be hard-pressed to know for sure.
179+
After all, we can simply re-order the node ordering along the axes
180+
to produce a seemingly-random matrix.
181+
"""
181182
)
182183
return
183184

@@ -186,15 +187,15 @@ def _(mo):
186187
def _(mo):
187188
mo.md(
188189
r"""
189-
## Arc Plot
190-
191-
The Arc Plot is another rational graph visualization.
192-
Here, we line up the nodes along a horizontal axis,
193-
and draw _arcs_ between nodes if they are connected by an edge.
194-
We can also optionally group and colour them by some metadata.
195-
In the case of this student graph,
196-
we group and colour them by "gender".
197-
"""
190+
## Arc Plot
191+
192+
The Arc Plot is another rational graph visualization.
193+
Here, we line up the nodes along a horizontal axis,
194+
and draw _arcs_ between nodes if they are connected by an edge.
195+
We can also optionally group and colour them by some metadata.
196+
In the case of this student graph,
197+
we group and colour them by "gender".
198+
"""
198199
)
199200
return
200201

@@ -212,9 +213,9 @@ def _(G, annotate, nv, plt):
212213
def _(mo):
213214
mo.md(
214215
r"""
215-
The Arc Plot forms the basis of the next visualization,
216-
the highly popular Circos plot.
217-
"""
216+
The Arc Plot forms the basis of the next visualization,
217+
the highly popular Circos plot.
218+
"""
218219
)
219220
return
220221

@@ -223,12 +224,12 @@ def _(mo):
223224
def _(mo):
224225
mo.md(
225226
r"""
226-
## Circos Plot
227+
## Circos Plot
227228
228-
The Circos Plot was developed by [Martin Krzywinski][bccrc] at the BC Cancer Research Center. The `nxviz.CircosPlot` takes inspiration from the original by joining the two ends of the Arc Plot into a circle. Likewise, we can colour and order nodes by node metadata:
229+
The Circos Plot was developed by [Martin Krzywinski][bccrc] at the BC Cancer Research Center. The `nxviz.CircosPlot` takes inspiration from the original by joining the two ends of the Arc Plot into a circle. Likewise, we can colour and order nodes by node metadata:
229230
230-
[bccrc]: http://circos.ca/
231-
"""
231+
[bccrc]: http://circos.ca/
232+
"""
232233
)
233234
return
234235

@@ -238,17 +239,16 @@ def _(G, annotate, nv, plt):
238239
nv.circos(G, group_by="gender", node_color_by="gender")
239240
annotate.circos_group(G, group_by="gender")
240241
plt.show()
241-
242242
return
243243

244244

245245
@app.cell(hide_code=True)
246246
def _(mo):
247247
mo.md(
248248
r"""
249-
Generally speaking, you can think of a Circos Plot as being
250-
a more compact and aesthetically pleasing version of Arc Plots.
251-
"""
249+
Generally speaking, you can think of a Circos Plot as being
250+
a more compact and aesthetically pleasing version of Arc Plots.
251+
"""
252252
)
253253
return
254254

@@ -257,10 +257,10 @@ def _(mo):
257257
def _(mo):
258258
mo.md(
259259
r"""
260-
## Hive Plot
260+
## Hive Plot
261261
262-
The final plot we'll show is, Hive Plots.
263-
"""
262+
The final plot we'll show is, Hive Plots.
263+
"""
264264
)
265265
return
266266

@@ -272,29 +272,28 @@ def _(G, annotate, nv, plt):
272272
nv.hive(G, group_by="gender", node_color_by="gender")
273273
annotate.hive_group(G, group_by="gender")
274274
plt.show()
275-
276275
return
277276

278277

279278
@app.cell(hide_code=True)
280279
def _(mo):
281280
mo.md(
282281
r"""
283-
As you can see, with Hive Plots,
284-
we first group nodes along two or three radial axes.
285-
In this case, we have the boys along one radial axis
286-
and the girls along the other.
287-
We can also order the nodes along each axis if we so choose to.
288-
In this case, no particular ordering is chosen.
289-
290-
Next, we draw edges.
291-
We start first with edges _between_ groups.
292-
That is shown on the left side of the figure,
293-
joining nodes in the "yellow" and "green" (boys/girls) groups.
294-
We then proceed to edges _within_ groups.
295-
This is done by cloning the node radial axis
296-
before drawing edges.
297-
"""
282+
As you can see, with Hive Plots,
283+
we first group nodes along two or three radial axes.
284+
In this case, we have the boys along one radial axis
285+
and the girls along the other.
286+
We can also order the nodes along each axis if we so choose to.
287+
In this case, no particular ordering is chosen.
288+
289+
Next, we draw edges.
290+
We start first with edges _between_ groups.
291+
That is shown on the left side of the figure,
292+
joining nodes in the "yellow" and "green" (boys/girls) groups.
293+
We then proceed to edges _within_ groups.
294+
This is done by cloning the node radial axis
295+
before drawing edges.
296+
"""
298297
)
299298
return
300299

@@ -303,35 +302,34 @@ def _(mo):
303302
def _(mo):
304303
mo.md(
305304
r"""
306-
## Principles of Rational Graph Viz
307-
308-
While I was implementing these visualizations in `nxviz`,
309-
I learned an important lesson in implementing graph visualizations in general:
310-
311-
> To be most informative and communicative,
312-
> a graph visualization should first prioritize node placement
313-
> in a fashion that makes sense.
314-
315-
In some ways, this makes a ton of sense.
316-
The nodes are the "entities" in a graph,
317-
corresponding to people, proteins, and ports.
318-
For "entities", we have natural ways to group, order and summarize (reduce).
319-
(An example of a "reduction" is counting the number of things.)
320-
Prioritizing node placement allows us
321-
to appeal to our audience's natural sense of grouping, ordering and reduction.
322-
323-
So the next time you see a hairball,
324-
I hope you're able to critique it for what it doesn't communicate,
325-
and possibly use the same principle to design a better visualization!
326-
"""
305+
## Principles of Rational Graph Viz
306+
307+
While I was implementing these visualizations in [`nxviz`](https://github.com/ericmjl/nxviz),
308+
I learned an important lesson in implementing graph visualizations in general:
309+
310+
> To be most informative and communicative,
311+
> a graph visualization should first prioritize node placement
312+
> in a fashion that makes sense.
313+
314+
In some ways, this makes a ton of sense.
315+
The nodes are the "entities" in a graph,
316+
corresponding to people, proteins, and ports.
317+
For "entities", we have natural ways to group, order and summarize (reduce).
318+
(An example of a "reduction" is counting the number of things.)
319+
Prioritizing node placement allows us
320+
to appeal to our audience's natural sense of grouping, ordering and reduction.
321+
322+
So the next time you see a hairball,
323+
I hope you're able to critique it for what it doesn't communicate,
324+
and possibly use the same principle to design a better visualization!
325+
"""
327326
)
328327
return
329328

330329

331330
@app.cell
332331
def _():
333332
import marimo as mo
334-
335333
return (mo,)
336334

337335

0 commit comments

Comments
Ā (0)