How-to: Joy plot
Since I created my first joy plot in autumn 2020 I have been obsessed. I will joy plot everything and anything. They are so much fun to make and are actually deceptively simple to create.
If you haven't come across joy plots before, they're essentially a series of layered line graphs which build up to give the impression of a 3D landscape. They owe their name to the cover of Joy Division's 1979 album Unknown Pleasures.
I first learned how to joy-plot by following this great tutorial by Travis White and I definitely recommend giving this a read too, particularly if you're newer to GIS: View of Cartographic Pleasures: Maps Inspired by Joy Division’s Unknown Pleasures Album Art (cartographicperspectives.org). This tutorial covers more around what I've learned since this great introduction.
To map along with me, you're going to need just four things and they are all free - hooray!
Some elevation data*
A study area polygon - this will be the extent that you'll be clipping your data to. It could be a country, a city, a national park boundary or just a rectangle. I'm going to be creating my plot today for Yellowstone National Park, so I'll be using that boundary.
*For this how-to I'm going to be using SRTM data which is an almost-global (sorry Greenland) source of elevation data which you can download for free here: https://earthexplorer.usgs.gov/. You can merge these together to cover your study area in QGIS using the Merge Raster tool (under raster > misc.) - make sure you choose the right raster type. If you're using SRTM data it'll likely be Integer 16 but make sure you check this under the information tab of your layer properties. Any form of elevation data in a raster format will work just as well - I've created some really fun joy plots with LiDAR data before. It also doesn't have to be elevation data - you could take population data, jobs, covid rates - anything! It just needs to be something that communicates magnitude, and it needs to be in a raster format.
Like with all things in the world of data visualisation, there are multiple ways to get to a result you want. This tutorial shows my method, and it's by no means the best method in the world - just the best for me in terms of my resources and skills. As you practice, you'll learn what works best for you, too.
Prepare your transects
First of all, we need our transects (horizontal lines) that will eventually turn into our elevation line graphs. I typically think you need around 100 lines to make a great joy plot, but you may want more or less depending on the effect you're aiming for - fewer lines results in more dramatic changes between each line, whilst more closely spaced lines will generate a smoother effect.
Add your boundary polygon to QGIS and zoom to its extent.
Run the Create Grid tool (found under Vector > Research tools).
Change the grid type to line and set the grid extent to use map canvas extent (assuming you're zoomed to your boundary layer) or calculate the extent from your boundary layer.
The horizontal spacing of the lines doesn't matter as we'll be deleting those in a second.
For the vertical spacing, divide the height of your boundary layer by about 100 (depending on how many transects you want) and that is the spacing you need. For me, Yellowstone Park is around 100km "tall," so I want a horizontal line about every 1km.
Run this tool.
Delete the vertical lines (right-click your layer in the Layers panel, and select Toggle Editing, then select the features and hit 'delete' to delete them). You may want to edit your lines to make sure you catch any specific geographic features you want, such as mountain peaks - just make sure to keep the spacing even.
Clip the lines to the boundary layer (Vector > Geoprocessing Tools > Clip). The input layer is the grid layer you just created, and the overlay layer is your boundary layer.
You should end up with something like this.
Processing elevation data
Next we'll create a point dataset, with points running along each of these lines for every pixel of your elevation data. We'll append an elevation value - as well as coordinates - to each of these lines, and then export the data to a csv for plotting in R.
Firstly, import your elevation data (or whatever you're using for your height source).
Run the tool "Generate Points (Pixel Centroids) Along Line" - this can be found in the vector creation toolbox. This will create a point along your line for every pixel in your elevation data. Note that the more detailed your elevation data, the more intensive this will be - for my area I have 404,630 points to collect this data for so I can do a lot of cup-of-tea making while it runs.
Alternatively if you're finding that this is resulting in too large a dataset, run the "Points along geometry" tool (under Vector geometry) to achieve a similar - albeit less detailed - effect, but where you can specify the spacing of your points.
Next we need to join our elevation data to these points, for which we'll need to use a point sampling plugin. To install this, go Plugins > Manage and Install Plugins... > search for and install the "Point Sampling Tool."
Open this tool - it'll appear under Plugins > Analyses. Ensure the layer containing sampling points is the one you've just created, and that the layer/bands to get the fields from is set to your elevation data layer (a quirk of this tool is that the layers you want to analyse need to be turned on). Run the tool - you should now have an elevation value for each of your points - this field will be called the name of the elevation layer you used.
The final stage of this in QGIS is to add coordinates to each of your points - to do this run the "Add X/Y fields to layer" tool (under Vector table). Export this as a csv file either at the time of the analysis or afterwards by right-clicking on the layer and going Export > Save features as... I'm imaginatively calling my data "coords.csv."
And now we're ready to joyplot!
The two main packages we'll be working with in R today are ggplot - an R stalwart for datavisualisation - and ggridges for working specifically with ridge plots. If you don't have these installed, open up a script in RStudio and use the code install.packages("ggplot2", "ggridges") to install them - and that's all you need!
The first thing we're going to do is load in our data and create a simple joyplot, shown in the code below.
Load the two packages we need - ggplot2 and ggridges
Read your csv that you previously created and create a layer with it - I'm calling mine "transects"
Load the names of your data fields and rename them something useful - make sure you're giving the fields the right names and not just copy mine!
Call a simple joyplot! You'll want longitude along the X axis and latitude along the Y, grouped by the latitude line each point originated on. The height of each line will be your elevation field, and by using stat = "identity" we're saying that we want to provide the Y values, rather than them be auto-calculated.
You should be left with something like this: your first joy-plot! It may not look pretty... or exciting... or that joy-ful, but it is a joyplot! Now we're going to go through how to style this Unknown-Pleasures-Style.
Unknown Pleasures Joyplot
There are two elements to this. Firstly, we're going to alter our actual ridges to make them a bit more exciting and stylised, as well as scaling them to make them a bit more exciting. Secondly, we're going to customise the theme of the overall plot to emulate the Unknown Pleasures style. What that means is a minimalist look, with a black background and white ridgelines, and not much else.
Within our geom_density_ridges section, we can scale our ridges (I chose to scale mine by 20, but what you choose will completely depend on your geography and desired effect) and then changing the fill to black and lines to white. Everything else we can change by adding a theme, stripping away all the marginalia and changing the panel and plot backgrounds to black.
And now you (should) have it! So fun, right? And surprisingly easy to do?
Why not try putting your own stamp on this? Below are a few different styles I've used in the past. You can do quite a lot just in R by altering the colours and weights of your fills, lines and plot/panel backgrounds. Sometimes I like to take this even further, exporting my plot as a PDF and importing it into Adobe Illustrator (you could equally use any vector-based graphics package such as InkScape) and playing with the style in there. My absolute favourite style is a 'snow-capped peaks' style, where I use a dark background, no linework and a gradient fill with the lighter colour at the top of the peaks. I also think it can look really cool to add in a subtle drop-shadow between each ridge-plot which can make the graph look a bit more tactile, almost like it's been 3D printed.
I can't wait to see what cool effects you can come up with - and tag me at @helenmakesmaps so I can see! I hope you enjoyed my first how-to! Let me know what you thought and what you'd like me to cover next!