# How to visualize distance vs. distance vs. size?

I'm trying to create a visual representation of the remoteness of several small cities/towns hosting refugees.

To give some details: when the refugees in question arrived in the 1950s in my country, the authorities hosted them temporarily in hotels in small cities or towns. It created some difficulties for them (e.g. to find jobs, because they were far away from everything, without cars and money).

The data looks like this (the actual data lists about 40 cities):

Host city/town  | Nb of refugees  | Km from the nearest admin. center | Km from the nearest "big city" (>20,000)
City A          | 60              | 22.5                              | 22.5
City B          | 120             | 0                                 | 0
City C          | 10              | 45.7                              | 10.2
City D          | 167             | 27.1                              | 27.1
City E          | 50              | 0                                 | 70
City F          | 200             | 41.1                              | 45.6
City G          | 37              | 16                                | 16
City H          | 188             | 35.6                              | 35.6
City I          | 21              | 40                                | 50.2


The two options I see to represent this data are:

1. A map, with proportional circles showing the number of refugees in these different cities, and markers to show nearby administrative centers and important cities.
2. A bubble chart, with the x-axis for the distance from the nearest administrative city, the y axis for the distance from the nearest "big city", and the size of the bubbles depending on the number of refugees.

I tried these two solutions, but with these particular data, I find that a map doesn't show well the distances, because the host cities themselves are very distant from each others.

The bubble chart makes the information more obvious, but of course there's a relation between the categories "big city" and "administrative center", which creates a sort of diagonal on the plot.

The problem is that it may give the impression that the point I'm trying to make is that there's a relation between the distance from an administrative center and the distance from a city with over 20,000 inhabitants (as an administrative city and a "big city" are often the same). Of course, this is not what I'm trying to show.

I plan to write a comment explaining this bubble chart, but I'm a bit afraid that this "diagonal" may be disturbing for readers, even with an explanation.

I do not try to infer anything from the data, I just want to show how far the the authorities generally hosted these refugees.

Does someone have a suggestion? Am I overthinking it? Is there another kind of representation that would be better for this use case?

Thanks,

• Do you really need to represent both distances? It seems to me that the community size is more relevant, hence it should be on the $y$ axis. I suggest that you choose for the $x$ axis the distance that is more relevant in your context. You may comment in the text when referring the figure that both distances are correlated (perhaps with a correlation coefficient). Aug 5, 2019 at 10:32
• @Ertxiem Not necessarily, but there's a significant number of "outliers" (the correlation coefficient between distances is "only" 0.25, yet the diagonal on the plot is really eye-catching). There were a significant number of people hosted near administrative centers, but far away from big economic centers, and vice versa. Even if I'd like to avoid losing this specific info, it's not a major point in the article, and keeping just one of these two distances is a useful suggestion. Thanks! Aug 5, 2019 at 13:47

Here's an idea: Overlaid bars with width=Refugee Count and length=distance. Both distances are overlaid with transparency. I like that the area of each bar (refugees x distance) seems to correspond to some amount total difficulty. I had to inflate the 0-km distances to 0.5 distances so you could still see their widths. I suppose some travel is needed even within the same city anyway.

I'm actually implementing this with custom-width lines in my software (JMP), which is why the legend items look like lines.

• Thanks for the suggestion! I guess an improvement could be to use a dot plot (maybe with dot sizes varying according to the number of refugees?), rather than a bar plot. Something a bit like that: python-graph-gallery.com/wp-content/uploads/…. However, as I have 40 cities to plot, I'm afraid this solution will make the chart quite difficult to read in my situation. I hope your solution will be helpful for other people, though! Aug 6, 2019 at 6:51
• Oops -- overlooked the 40 cities part. Yes, dots might work in this configuration since they would tolerate overlap and, given the sqrt scale of dot areas, wouldn't have to be so big to see the full range of values.
– xan
Aug 6, 2019 at 15:03

You could overlay the name of the hosting cities, but, as I understand it, it's not imporant which cities are hosting the refugees, rather their distance from admin or big cities. One drawback of this graph is that each group of refugees is plotted twice (once for admin and once for 'big city') but you could number each group to make clearer that they are duplicates.

Here's the R code:

library(data.table)
library(ggplot2)

rfg
1:    City A         60  22.5     22.5
2:    City B        120   0.0      0.0
3:    City C         10  45.7     10.2
4:    City D        167  27.1     27.1
5:    City E         50   0.0     70.0
6:    City F        200  41.1     45.6
7:    City G         37  16.0     16.0
8:    City H        188  35.6     35.6
9:    City I         21  40.0     50.2

rfg <- melt(data= rfg, id.vars= c('host_city', 'n_refugees'), variable.name= 'nearest', value.name= 'distance')

gg <- ggplot(data= rfg, aes(x= distance, y= n_refugees, shape= nearest, colour= nearest)) +
scale_shape_manual(values=c(3, 4)) +
geom_point(size= 3) +
xlab('Distance (km)') +
ylab('Size of refugee group') +
ggtitle('How dislocated are refugees?')

• Thanks for the suggestion! Indeed, the problem is that I want to keep the link between the two distances. I think that numbering the groups would be an elegant solution if I had just 10 or 12 points to plot, but with with 40 cities to plot (i.e. 80 points), I'm afraid it will be hardly readable! Aug 7, 2019 at 20:42

Since my previous answer from 2019 (which I don't recommend), I found two other possibilities: pyramid plots or network visualization. If you have data similar to the dataset described in my question, both solutions involve either data wrangling and/or collecting additional data. Here is my approach for these two solutions, that can probably be improved further:

Solution 1, split barplot/pyramid plot:

Heavily inspired by xan's answer (thanks!), but with a tweak: a barplot, similar to a population pyramid, where the unit of measurement is an individual refugee, instead of a group of refugees. So the Y axis is no longer categorical, but represents the cumulative number of refugees. In addition, the X axis is split between two sides. In my case, it required transforming the dataset, but it wasn't really complicated to do.

Below is the result (probably clearer than my explanation). The vertical red line represents the number of refugees, the bars on the left represent the distance to the nearest administrative center, and the bars on the right the distance to the nearest big city:

Example of reading: about 200 refugees were at 40 kilometers or more from an administrative center or a big city. Additionally, a relatively small group of refugees was located in an administrative center which itself was at more than 60 km from the nearest big city. Finally, about 600 refugees were at 20km or more from an administrative center or a big city.

• It gives a pretty good idea of how many refugees are very distant or very close to big cities/admin centers, depending on what you're interested in.
• You can identify outliers, for example the very noticeable long blue bar on the top of the graph.
• You can identify groups based on their distance to the nearest city of interest. Note that this is different from the original groups, more on that below.

• It may require an explanation if you communicate the graph to an audience not familiar with data visualization.
• You lose the information about individual cities, for example if a group of refugee A is in a different city from group B, but both groups are at an equal distance from an administrative center and from a big city, you can mistakenly think they're originally from the same group. It might be possible to tweak the visualisation further to distinguish original groups from each others. Maybe something similar to Xan's answer, but including the "right/left" split on the X axis, instead of overlapping the two categories. I'm not sure it would work with a really big dataset.
• You may overlook the refugees who are at a "0 km" distance, i.e. the part of the vertical red line without bars on its right or on its left. A solution may be to tweak the dataset to add 1 or 2 kilometers to the 0 km distance.
• Depending on what your original dataset looks like, ending up with this kind of visualisation might be difficult, but it's a programming issue, not a visualization problem.

Solution 2, network visualization (requires additional data)

In my case, network visualization has the advantages of a map, without some of its downsides, e.g. if some cities are very distant from each others (e.g. hundreds of km), it somehow obfuscates the distance between refugees and cities, making it apparently very small in comparison (i.e. 60 km may look very small depending on the map scale).

Depending on your dataset, network visualisation may require data wrangling and additional data (e.g. in my case, it may require identifying uniquely each administrative center and each big city), but it might be worth it and may give additional insight.

Here's a very crude example, but you get the idea, i.e. we use cities and groups of refugees as nodes (with varying colors and sizes), and distances as edge length:

Information represented: the relative distance (=edge length), the size of each group of refugees (=circle size), the type of city (=circle color), the city size (=circle size).

• It allows to identify important cities, clusters, etc. Additionally, the data wrangling process may allow you to perform network analysis on the transformed dataset.
• On a map, if the big green circle and big blue circle had been distant for hundreds of kilometers, it would had been very difficult or impossible to plot all these information without creating clutter and overlapping circles. Network visualization removes this obstacle, e.g. if in this visualization we treat the direct distance between the two big blue and green circles as irrelevant.

• You might only be able to visualize relative measurements (distance, size). To get the exact measure you're interest in, you'd probably have to refer to the original dataset. For example, you can see that some groups are relatively closer to big cities than others, but you don't know by how many kilometers exactly. Maybe adding some textual information on the graph could solve the issue (e.g. adding a label on each edge mentioning the number of km), but a risk is to clutter the graph. Otherwise, using the legend may or may not do the trick, but I think it depends on your dataset.
• Circle size is used to represent two different variables (group size and city size). It does not necessarily create a problem of interpretation if you use a color to distinguish refugees from cities, but it may require some manual customization to avoid some circles becoming too big or too small.
• Depending on the tool you use, it may take a while to create a correct visualization, i.e. choosing the right algorithm (here I used Force Atlas followed by expansion, and tweaked a couple of things manually), customization, adding a legend, maybe transforming the data, etc.
• Not sure of how well it works if you have a boatload of data, in particular if you need to perform a lot of manual tweaking. Solution 1 might be better in this situation.

I don't recommend this answer, but leave it in case it might be useful for other use cases.

I finally chose to use a bivariate kernel density estimation plot.

I had to transform the data to do that:

Refugee ID      | Host city/town  | Km from the nearest admin. center | Km from the nearest "big city" (>20,000)
1               | City A          | 22.5                              | 22.5
2               | City A          | 22.5                              | 22.5
3               | City A          | 22.5                              | 22.5
...
853             | City I          | 40                                | 50.2


Then I estimated the bandwidth with statsmodels KDEMultivariate, and plotted the data with seaborn.kdeplot:

Some information is lost, but I find it's a good compromise.

I find that the diagonal is less disturbing than with a bubble plot, as the density and the separation in three groups is more eye-catching than the diagonal form. It allows to easily identify groups in the data.

There may be a better solutions to this problem, but I hope this suggestion will at least help other people.