25 min read
In this series of posts, I roam and gauge the design space of network maps. The series presents and discusses common solutions to the main readability problems that arise when visualizing large networks (1000+ nodes) as dot-line charts, typically based on a force-directed layout or equivalent. The series is aimed at helping multiple publics: beginners who have to choose the settings of a network map (in Gephi or another tool), tool-makers whose tools have to generate network maps, and graphic designers who visualize networks.
One of my goals is to find the best rendering approaches for Gephi and Gephi Lite. This series exposes my rationale so that it can be discussed and criticized. But I will extract do’s and don’ts and takeaways along the way, so that you can also get reusable, practical insights about visualizing networks.
My choices are opinionated. In particular, I will prioritize what I consider the raison d’être of network maps: the layout. I will always aim to have the layout jump at the face of the reader. My criteria for readability are partial. Let me explain in the next section, or jump ahead to the illustrated examples.
Criteria used to assess the readability of a network map
For the sake of the discussion, I will assess the network maps according to a non-exhaustive list of 11 criteria. I selected those because they capture the main practical problems of visualizing a network map. The problems we meet are of two kinds: contrast (legibility of the elements) and mediation (validity of the message conveyed).
My criteria
- Do the nodes contrast with the background?
- Do the edges contrast with the background?
- Do the labels contrast with the background?
- Do the nodes contrast with many underlying edges?
- Do the labels contrast with many underlying edges?
- Do the labels contrast with many underlying nodes?
- Do we see which edges are connected to a given node?
- Does the heterogeneity of the node distribution jump at our face?
- Can we identify the edge bridges between clusters?
- Context: how many labels can we read?
- Colored communities: can we see distinct groups of colored nodes? (typically in a situation of community detection)
Contrast issues (criteria 1-6)
Network maps generally have:
- A background
- Nodes
- Edges
- Labels
I will focus on those four elements, and I will also consider what happens if edges are not displayed. But I will omit other things that may also have to fit, such as annotations.
Obviously, nodes, edges, and labels have to contrast with the background. But there is more to it. New problems arise in specific situations, for instance if there are so many edges that they act like a new background. We must also consider the contrast of nodes and labels over edges, and of labels over nodes.
Mediation problems (criteria 7-11)
Reading the map of a small network is about following the paths. The reader wants to know who is linked to whom. A problem arises when a line intersect a node, because there is an ambiguity about whether or not the node is connected or just happens to be over an edge. This leads to path-reading mistakes.
Conversely, reading the map of a large network is generally not about following the paths, because there are too many edges anyway. Here, I assume that the visualization mediates the topology via the layout, rendering communities as visually dense node groups (clusters). The edges are implicitly encoded into the clusters, i.e. the spatial distribution of the nodes, also called the embedding. The main threat to appropriately understanding a network map is the obfuscation of its node distribution. The layout must be prominent and readable, as it is the main feature used to interpret the topological structure of the network.
It is therefore worth remarking that there is a tension between the readability goals of, on the one hand, the nodes, and, on the other hand, the edges and the labels. The node clusters are better visible when there the visual space between the clusters is empty. This negative space makes the structural holes visible. Yet on the other hand, edges precisely occupy the space between the nodes, filling this empty space. Worse! As labels cannot overlap, they tend to occupy space homogeneously, obfuscating the heterogeneity of node distribution. The typographic gray of the labels may hide the layout, which we want to avoid at all costs.

Then, there is a secondary problem. Even for large networks where displaying edges is less useful, it may be important locally. The typical situation is the presence of a bridge between two or more clusters. If the edges are not displayed, analyzing the topological situation of that node is difficult. Compromises are needed.
Finally, I want to mention a problem that I will not address here. Since the principle of the layout is to bring connected nodes closer, edges should be as short as possible. In some sense, they are, but it’s impossible in practice to make all edges short, so some edges have to be “sacrificed”: they will be allowed to be long so that even more edges can be short. To assess the success of the layout, one should look at the short edges. Unfortunately, short edges are the less visible, because they occupy less graphic space. It is the long edges that attract our attention, but those are not necessary the most important ones. It depends on your questions: long edges are those we want to see if we look for bridges, but not if we look whether where the layout manifested topological clusters.
The case: Airlines
In this series, I will visualize a single network: airports connected by airlines in 2021. It comprises 3290 nodes and 37411 edges. The layout, computed with Force Atlas 2 in LinLog mode, is always the same. The edges are weighted and directed, but I will ignore it entirely in this series. I do not deny that this aspect is very important, but I left this question aside precisely because there is already a large discussion of this aspect of network visualization.
I will most often offer three views of the visualization, at three different levels of zoom, and on different parts of the structure. They will always be the same so that you can compare. Click on them to check the full resolution.



The full map is rendered for a poster of 1 meter by 1 meter (the same surface as a A0 paper sheet) printed in 300 dpi, which also corresponds to a reasonably zoomable on-screen image (11811 x 11811 pixels). The details are rendered to be visible from very close or zoomed-in (smallest font size: 8 pts) while some patterns should be visible at a distance or zoomed-out (largest font size: 24 pts).
Black and white network maps
Here I look at the simplest case: black, white, and no levels of gray or colors. I will generally assume that the background is white, but a black background is just the same thing in negative. My points about contrast implicitly apply to the inverted images.
The priority is always to have nodes visible over the background, so nodes have to be, somehow, black. They might have a black border and a white fill, but I will start by considering them simple black dots.
Just black dots
It may surprise you, but displaying just black dots captures the essence of a large network visualization (the layout), although it does not work well for a small network (because we do not see the paths).



Assessment: nodes contrast well with the background and the layout is quite prominent, but we don’t see where the bridges are, and without the labels, we lack context.
DO: place and size the nodes so that we can separate them visually. DON'T: make the nodes so big that they overlap and get undistinguishable.
When nodes are too big, dense areas get confusing:



Note: in this case, the bigger nodes make the layout pop out even more, which is good. But there are other ways to do so that do not have the drawback of amalgamating the nodes.
DO: place and size the nodes so that we see where they are. DON'T: have some nodes so small that non-empty areas look empty.
When nodes are too small, the reader has to focus in order to find where the nodes are:



Black dots + lines
To see edges over a white background, we have to draw them black. The most obvious choice is to draw the nodes in black. The straightforward implementation works for small networks, but not for large ones, because the nodes become invisible over many edges, and because one does not see exactly which edges connect to which nodes. Edges also downplay the layout. Check it out:



Assessment: nodes do not contrast well with edges, we do not see which edges are connected to which nodes, and the layout is not that clear although we now see the bridging edges. Let us explore different ways to solve these issues.
Solution 1: very thin edges
The simplest solution is to have the edges so thin that they never compete with the blackness of the dots. This options is not always available, either because the printing process is not precise enough, or because there are just too many edges.



Assessment: nodes now contrast fine with edges, and the layout is more visible.
This solution is only as good as the gray texture resulting from the overlapping of edges remains light. The example above is acceptable but not great. In practice, the visual separation of black dots over the lines can range from the worst to the best. This solution is valid but not universal.
Solution 2: white edge borders
This solution is always available, and guarantees that edges never paint the background entirely black.



Assessment: it improves the contrast of nodes with edges, the readability of the layout, and slightly helps to see which edges connect to which nodes.
I like that this trick is not intrusive for sparse networks; it may even help! However, it has flaws. First, the texture obtained gets distractingly busy in dense areas. Second, the edge drawing order now matters. I recommend drawing shorter edges on top (last), because long edges have less chances to get entirely obfuscated. Third, it gets harder to track edges through dense areas (because the borders ultimately hide a lot of information). Besides those flaws, it does not improve much reading which edges connect to which nodes, because edges connected to a given node can easily get obfuscated.
Solution 3: white node borders
It specifically fixes the contrast issue of nodes over many edges. The node borders must be thick enough to ensure that they pop out even at a reasonable reading distance.



Assessment: it only slightly improves the contrast of nodes with edges.
This solution has multiple flaws. First, it becomes less obvious that edges connect to nodes, as it seems that they pass below nodes. The visual pattern is ambiguous. Second, the nodes over moderately dense areas where the edges make busy visual patterns, the nodes are not visible enough. The border only helps when the edges are so dense that it gets completely black. Third, and as a consequence of the previous point, we do not improve the sense of the spatial distribution of nodes. That is the main problem, and it does not fix it. For those reasons, I recommend against this approach.
Large borders improve the readability of the nodes and their distribution, but you may run into problems as soon as the borders get as large as the gaps between the nodes, as nodes will now overlap. Check it out:



The proper implementation is to draw all the node borders, then all the nodes without border, on top, as two separate layers.
Solution 4: very large node borders
With this solution, the node borders can become arbitrarily large. Functionally, they become something else. From there, I will call those large borders “halos”. For reasons that will appear later, I will even precise that those are “flat halos”. In short, halos can have a gradient which greatly helps with readability, but that is not available in the pure black-and-white case that we are considering for now.



Assessment: The contrast of nodes with edges gets good, and the layout gets more readable, but reading which edges connect to which nodes gets from bad to worse.
These flat halos can get arbitrarily large, which means that we can preserve the readability of the layout as much as we want, at the detriment of the edge readability. Indeed, not only do we lose clarity on which edges connect to which nodes (which was already problematic), but we also lose the general feeling that edges connect to nodes in general. The nodes seem to float over the edges.
That being said, this solution is compatible with the solutions 1 and 2. It is notably consistent with edge borders, but combining them is not that productive. Let us see what it looks like.
Solution 5: edge borders and very large node borders (flat halos)
It makes sense to combine node borders and edge borders, but since they have a major common flaw, reading which edges connect to which nodes, which does not get fixed.



Perspective on the contrast problem
At this point, if your intuition is like mine, you probably think: we should just extend the edges that connect to a given node through its halo! This way, we would conversely improve the readability of which edges connect to which nodes. And you would be right. In black and white, it looks like this:



Assessment: the contrast of nodes with edges gets good for most nodes (but not the most connected) and it becomes suddenly possible to get a pretty good sense of which edges connect to which nodes.
This technique is very promising, but I will not explore this direction for now. Indeed, to put it simply, a good implementation is complicated to design due to non-obvious issues. We will that technique anyway, and it makes more sense if one can use levels of gray. In an actual use case, for instance a figure in a black-and-white academic paper, it would make much sense to reduce a high-contrast but gray image to a black-and-white version through techniques like dithering. So for now, I am just acknowledging that the technique is a promising direction to explore later on.
White dots + black lines
Let me introduce a non-obvious approach known to me as the “Grandjean trick”, because I learned it from Martin Grandjean. On a white background, we have to draw the edges in black. But we can draw the nodes in white, provided that they have a black border:



Assessment: Compared to black dots and lines, we get an improved contrast of nodes with edges, although we lose some contrast of (disconnected) nodes with the background. The layout is also more readable.
In empirical networks like this one, we often have a few nodes that have many edges, and many nodes that have a few edges (aka a power-law distribution of the degree). It is also a common practice to set node sizes so that nodes with many edges are bigger. When that is the case, the Grandjean trick has multiple upsides. The large nodes are generally over a dense background of edges, precisely because they are the most connected. They are visible because they appear as big white dots over a quasi-black background (made of edges). The small nodes, on the other hand, are on the normal white background because they are poorly connected. But being small, their border matters more than their surface, and their border is black, so they remain visible. The border-to-surface can be set so that it compensate the kind of background where nodes lie, depending on their size.
That being said, there are some flaws to this technique. Mid-sized nodes are not very visible. The distribution of edges is more visible than the distribution of nodes, which is misleading (as it depends on it). And the need to read which edge connects to which node remains unaddressed. Yet the trick excels at making cluttered networks readable, which is invaluable.
The Grandjean trick is so easy to implement that basically every graph drawing system allows it. The only two points of vigilance are that it works only when node size is at least roughly aligned with the degree, and that the border size must be approximately the same as the size of the smallest nodes.
White dots + black lines with borders
The point of the Grandjean trick is to have the big (hyperconnected) nodes emphasized in white against the blackness of the underlying edges; but the point of edge borders is to mitigate that blackness. It is therefore an unlucky combination. Here is an example with relatively thin edge borders and edge thickness consistent with node borders. The idea is to emphasize the connection between nodes and edges. It still works poorly, mainly because the distribution of nodes remains relatively hard to see.



DON'T: use white nodes over edges with borders.
Takeaways about edges
Before we explore how to render labels, let us recap what we have seen about edges in black and white.
Drawing edges as thin lines is the best solution if available. The goal is to draw edges thick enough to see every edge but thin enough that the accumulation of edges does not become too dark, as it must not hide the distribution of black dots. It is not always possible, either because the network is too dense at places, or because the medium prevents drawing lines thin enough (low quality print).
If thin edges are not available, the next best thing to do is to use the Grandjean trick. Drawing edges with a border is never as good, as the pattern it creates is so distracting. The Grandjean trick is resilient, and works best with complex networks (they have very dense areas). It is the safest bet when thin edges don’t work.
The problems with labels
Labels come with two important problems: labels occlude each other, and they occlude the nodes. Those cause two different issues that we will address separately.
The second issue is the most critical, as hiding the layout makes the network map pointless. But solving the first issue will help with that. So for now, let us focus on the first issue, labels obfuscating each other.
In general, one cannot display all labels and have them readable at the same time. Indeed, the smallest nodes tend to be closely packed, and the labels would have to be very small to not overlap. I will acknowledge that it can still be done for vector rendering (PDF, SVG…) opened on a computer, because we can zoom in as much as we want; but vector graphics break when there are too many edges, among other problems.
In this piece I focus on a generic use case, where the output image can be printed or visualized on screen. I calibrated the rendering to a regular poster size, where the smallest labels can only be read from pretty close (font size 8 pts) while the biggest labels can be seen at a distance (font size 24 pts).
Black dots + all labels
Let us start with a naïve rendering to address the issue.



As you can see, the overlaps are absolutely massive. The labels would have to be much, much smaller to avoid overlaps; so small that one could not read them even on a very large poster.
DO: if you need to, pick the most important labels and display only those. DON'T: display all labels, as they would generally overlap massively.
Precisions: following a common practice, I set the labels bigger for the bigger nodes; I drew the large labels on top, because the purpose of making some elements bigger is to emphasize them; I also used a white border around labels to separate them visually, which is strickly better than no borders. I see those choices as non controversial.
Depending on your tools and methodology, you may find a way to only display the labels of certain nodes. They may be manually picked, or filtered down following a criterion (ex: top 100 nodes by degree). This does not guarantee the absence of overlap, but may mitigate the problem sufficiently for all practical purposes.
Yet the apparatus should be helping. From the standpoint of the tool maker, we should be alleviating this burden if possible. Indeed, there are algorithmic ways to address the problem of label collision. I will address that aspect here.
Black dots + some labels
From there on, I will make use of a slightly advanced technique. I will detect collision between labels, and simply omit the smaller label when it collides with a bigger one. This ensures that the nodes that require emphasis get their labels displayed in priority. I described the technique and proposed an implementation in this Observable notebook.



The labels do not obfuscate each other anymore, and the dots are now visible. Which leads us to the second important problem: labels obfuscate the dots.
The problem gets worse as labels get packed more densely, as in this picture:



Even though the labels do not overlap, we do not see the dots very much. The issue is, in fact, twofold. First, we do not see some of the dots because they are covered by labels; but the labels still tell us that there is something there. Second, the labels compete visually with the dots. In short, it looks like every label is hiding some nodes, even when it does not.
The effect is not obvious because the general shape of the network remains visible. But densely packed labels create a texture that is gray on average and hides an important information about the density of nodes. We do not distinguish anymore between moderately dense and very dense areas. All areas with nodes look similar.
The effect can be made visible by blurring the image, calibrating its contrast, and posterizing it into a fixed number of levels (here, 8). Functionally, this boils down to a kernel density estimation of the black pixels rendered as a stepped heat map. In other words, the blacker an area, the denser its surroundings. If we apply this process to just the black dots, we see that some large areas remain gray: they are less dense than the black areas. If we apply the same to the image with the dense labels, we see that every area gets about the same level of blackness. The nuance about density has been lost. We also see that the clusters have bled left and right; naturally that is because labels expand horizontally (in this case).


The bottom-left cluster’s density appears too high with labels.
In black and white, we can mitigate this effect by lowering the label density. In practice, it can be done by offsetting the hit boxes of the labels during collision detection. We have to significantly lower the number of displayed labels if we want the nodes distribution to be effortlessly visible. And despite this, the labels will keep competing with the nodes visually to some extent.



The takeaway is simple: as soon as labels visually compete with dots, the spatial distribution of nodes, which is the most important thing, gets less readable.
DO: keep enough space between labels so that the layout of the underlying nodes is clearly perceptible. DON'T: cram so many labels that they obfuscate the layout.
About font weight
To improve the situation, I like to use an opinionated trick. It is worth sharing here, as it helps mitigate a little more the occlusion of nodes by labels, even though it sensibly complicates the implementation of label rendering. I generally like to compensate font weight across sizes so that every label seems to be drawn with the same pen. In other words, large labels get a lighter font and small labels get a bolder font. As large labels take up more space and often lie above dense areas, reducing how much they hide has some impact. It also ensure a better graphical consistency. However, it also makes the large labels pop out less, which might be an issue.



Assessment: The contrast of nodes with the background, of labels with nodes and with the background, are good. The layout is visible enough, and we can read enough labels to get some context, although the amount of text information has to remain limited.
I favor this approach because in a practical situation, I often prefer keeping the labels dedicated to close reading and have other layers dedicated to distant reading, like very large annotations of the main clusters.
It is also worth mentioning that the technique is far from obvious to implement, if only for the reason that it is not font-agnostic: different fonts stage their actual thickness differently across weights. Variable fonts solve this, but that technology is not available everywhere. So unless you engage with advanced scripting, you will probably have to overlook this trick.
Black dots, thin edges, labels
We will now combine edges with labels. As we have seen, we should consider two situations: do edges accumulate to the point they become a black mass, or do they not?
Let us assume first that we can draw thin edges that never get so dark that we do not distinguish the nodes. Following the same logic, we want to minimize the occlusion caused by labels, and keep the spatial distribution of nodes readable.



Assessment: The contrast of nodes, edges, and labels with the background is perfect. That of labels with nodes is good, and that of nodes with edges is good enough. However, the contrast of labels with edges is disappointing, as their textures are somewhat similar. The layout’s clarity is also disappointing, as so many elements compete with it. At least the bridges are visible, and we have some context from the labels, which still makes it our best visualization so far.
In our case, the result is acceptable but not great. In particular, the white border of the labels now makes them pop over the dark texture of edges, which creates an unwanted distracting pattern. This approach would work better on a slightly sparser network.
White dots, edges, white labels
We now assume that there are too many edges, and they will agglomerate into a black mass no matter what. We pull the Grandjean trick of having white dots circled in black. For the same reason (readability over a black background) we also invert the labels. They are now white with a black border.



Note: I had to make the labels a bit thicker to have them properly readable.
Assessment: Compared to the previous strategy (black dots, thin edges, labels) we slightly improve the contrast of labels with edges, but we lose contrast of the nodes with the background, and the layout get more difficult to read.
The strategy does not work that well with labels and in black and white, but it remains a valid option for very dense networks.
Black and white: takeaways
- Use thin lines if the nodes remain visible, else go for the Grandjean trick (white nodes with a black border).
- If you go for the Grandjean trick, apply it to labels as well.
- Either way, do not display too many labels because they tend to hide the spatial distribution of nodes.
That being said, black-and-white pictures can also be derived from grayscale pictures through dithering, which will provide more options. My reason for starting with black and white was to highlight the inherent contrast problems of network visualization. If we check my criteria assessing the visualizations, we find that some of them are never satisfied (seeing which edges connect to which nodes), while others always work (the contrast of nodes with the background). This tells us which challenges we face, and where we can intervene to improve the our visualization.
- Unproblematic: the contrast of nodes, edges and labels with the background.
- Increasingly problematic: keeping the distribution of nodes (the layout) prominent, identifying the bridges.
- Always problematic: reading which edges connect to which nodes.
We see a tension inherent to cartography: we can improve the visualization by adding graphical elements, but those elements simultaneously damage the general readability by competing with each other. That is why we have to pick each additional layer carefully, and find ways to avoid competition between layers if we can. Let me call this the curse of contextualization.
In my view, since the most important information comes from the spatial distribution of nodes, the challenge of network visualization is almost entirely dominated by the curse of contextualization. Indeed, as we have seen, just representing the nodes as black dots is already great at conveying the most important information. But as soon as we add other necessary contextual elements, we damage the most important thing (the clarity of the layout). Hence what I see as our top priority: preserving the layout’s ability to jump at the reader’s face.
Our second priority is to improve an aspect that we failed to address so far: clarifying which edges connect to which nodes. This will lead us to designing node halos in the next post of the series.
In order to do that, we will compromise with the aspects that have been unproblematic so far: the separation of nodes, edges and labels over the background. It would be productive to weaken it a little bit if it helps us reaching our two top priorities.
OpenEdition suggests that you cite this post as follows:
Mathieu Jacomy (May 3, 2023). How to render a network map, part 1: black and white. Reticular. Retrieved February 19, 2025 from https://reticular.hypotheses.org/6381
How do you feel about Lombardi graph format? I think it matches your criteria for easy legibility while not over-simplifying quite well.
python package http://lombardi.cs.arizona.edu/downloads.html
graphing software in other coding languages which may be helpful for embedding interactive social graphs in websites: https://lombardinetworks.net/software/
(Polinode is also supposed to make live online interactive graphs but I haven’t managed to make it work yet.)
p.s. helpful references about why it’s important to not over-simplify: James Scott (1998), Seeing Like a State, pp.19-20 in the pdf page numbering, about the dangers of over-simplifying social maps; and Yaneer Ban-Yam (2002), Complexity Rising, for the point about optimal complexity profile/s of social networks.
The actual networks by Mark Lombardi are rather small networks, and their priority is not to convey the structure via the node positions, because the network is small enough that we can grasp the structure by walking the paths. For his largest networks, he had paid attention to highlight the structure via different means. It was always ad-hoc, as a good design should be; it was curated. That is the purpose of the circular silhouette in networks like this one for instance:
https://www.pierogi2000.com/artists/mark-lombardi/#jp-carousel-2032
Now for the library, it is by definition not ad-hoc even though it tries to grasp drawing rules from Lombardi’s work. It remains dedicated to small networks, while the purpose of this post is about large networks. And this is not about technical scalability; it is about what it means to read the visualization. For a small network, reading is following the paths, so minimizing overlaps is the priority for instance. While for large networks, following the paths is hopeless, so one must pivot to highlighting the layout instead. Different reading rules, different modes of interpretation.