In the past several years I've had a couple of occasions to produce maps at the behest of the Norman B. Leventhal Map and Education Center at the Boston Public Library—once as a participant in an exhibition and as their Designer-in-Residence—and on both occasions I ended up making modern maps in a kind of 19th-Century style. I guess there's just something about that place that makes me want to design old-timey maps.
For the last year or so, from time to time, I've tried to turn these and other non-digital cartographic styles into something, well, digital and repeatable, specifically learning how to cobble together some antique and hand-drawn styles in QGIS. Since I signed up to speak about this at the 2024 NACIS conference, that means I finally need to share whatever I've learned so far!
Toward imperfect cartography
This is the One Weird Trick to using a computer to make a map that looks like it wasn’t made with a computer: make a lot of tiny mistakes! A computer can make a perfectly straight, perfectly spaced dots, perfectly even color fills, and so on. And it can do it every time. Humans cannot. Just about every tip below for fake antique maps includes a step to make the map look less perfect.
That means the word “random” is going to appear a million times in this article, because little random variations are the key to making QGIS turn clean, perfect vector data into something that looks like a human drew it. (Or printed it in some pre-digital way.)
Pillars of imperfection
If you just want to download my styles and look at them yourself, feel free to skip ahead. But I want to explain some general techniques and approaches that I've found myself repeating over and over, in the hopes of helping you adapt my styles to your purposes and/or come up with your own. If you're interested, read on!
Style expressions and random numbers
Nearly every symbology option in QGIS comes can be defined by an expression rather than a single static value. A simple example might be to set each feature's stroke width using data values from the attribute table.
For hand-drawn styles, the big thing is that expressions offer many opportunities to introduce randomization to our symbols. Computers can draw perfectly consistent straight lines, etc., but most human hands—and some archaic printing technologies—cannot. Slight randomization of line widths, point placements, rotations, colors, and so on give the impression of a human touch.
The two functions that appear over and over in most of my styles below (and will in yours too!) are rand()
and randf()
.
Geometry generators
Geometry generators do an amazing job of making your nice, neat shapes look like something else, and there are particular techniques for particular styles, but these are a few essential ones to make lines and polygons look more natural and hand-drawn.
wave_randomized
: add a little wiggle to straight lines. Experiment with the amplitude and wavelength parameters to achieve something subtle and barely noticeable. My goal is usually to make it look like someone was trying to draw a nice, neat line. (Unless you're going for that "uncharted territory" look where wobbliness is part of the character, in which case go nuts!)simplify
orsimplify_vw
: reduce the geometry to a more general shapesmooth
: increases geometry complexity, but makes things look more rounded
Often, some combination of all three is involved. Note that these slow down map rendering. You can run simplify
and smooth
as geoprocessing tasks to save permanent changes, instead of on the fly every time you move the map.
Layered symbols
The symbology for a vector map layer does not need to be a single line, fill color, or the like. Rather, it can comprise a stack of any many symbols as you want.
In this way, you can combine perfect things to make something imperfect. A circle is neat, for example. A circle combined with a star combined with a another dotted line circle combined with... well, things start looking messy!
An additional benefit of doing things this way is that you can cobble together custom shapes and patterns without the need for creating external raster or vector (SVG) assets.
Some go-to techniques
Below are a few techniques that I turn to nearly every time I want to do something that looks hand-drawn or old-fashioned. They might be used by themselves, or they might be part of more complex symbols, some of which will be mentioned farther below.
Rough, uneven ink
In addition to shapes being imperfect, I want the ink from the imagined pen or printing press to be a little uneven. My standard approach for lines or polygon outlines is to use a standard simple line combined with a marker line made up of the "line" marker, where each marker has some random variation in length and width.
Point marker symbols can be made more rough, too, by adding two or three strokes that have different stroke styles—dot line, dash line, etc.
Sketchy fills
For some reason I often want filled polygons to look like they've been scribbled in by pencil or crayon or something. So I may as well include my way of doing that!
This kind of style is built upon a point pattern fill. The point symbol is the "line" marker; each marker has some randomization of rotation, width, and length; the marker color has some transparency; the pattern spacing is close enough to leave only a tiny bit of empty space; and lastly the pattern also has a bit of randomization.
Painty fills
The other fill style I often turn to is something like watercolor paint, a solid color with a bit of inconsistency in how much "paint" there is across the shape.
I start with a simple solid fill in a kind of light version of the desired color. On top of that goes wither a point pattern fill (with randomization in point placements) or a random marker fill using one of he more interesting point marker symbols, like a heart and a more intense version of the color. These are then fairly strongly blurred via the draw effects option. The blurry symbols could be either in the same layer as the solid fill, or in a duplicate layer on top if you want to try a blending mode.
Paper textures
The map canvas itself can have some imperfection, too, hinting at things like the texture of paper or aged, fading ink. I like to try textures as vector styles, rather than raster images, because everything is contained in the QGIS project and there are fewer assets to keep track of. Here are a few tips.
- Random marker fills can be used for textures, for example a paper grain texture made from a random marker fill with "line" simple markers and a bit of random rotation.
- For a texture or effect covering the whole map, make a new polygon temporary scratch layer, and choose inverted polygons as its symbol type. The layer will appear as a polygon covering the map canvas, which you can style for texture effects. It will still be there if you change the map extent, and if you save the project and come back later.
- Use low opacity and blending modes like multiply and screen (depending on the desired effect) for subtle textures that overlay the entire map.
- For a faded look, do something like the "painty" fill described above (a blurred point pattern fill) with a light color.
Coastal hatching
Coastlines and water bodies are some of the most striking elements in old-timey maps, being both decorative and functional: they have an important job of providing figure-ground contrast when things weren't so simple as clicking on different fill colors.
Coastal hatching—parallel lines emanating from coastlines—is common in a certain type of antique map, and is especially useful as a kind of shadow to create some figure-ground contrast between land and water when color fills aren't an option. My version of it is done as a point pattern fill in buffered polygons, with a lot of randomization to make it look roughly sketched. There's a lot of room to tone down the randomness and still achieve a hand-drawn look here.
If you're using color, this pairs well with a kind of glow or shadow, like the darker blue seen under the hatching in the above screenshot.
Water lines
You can probably find a million articles and tutorials on this—basically just a series of buffers—but I'll mention my own tip anyway. You can make a multi-ring buffer with a geometry generator as in the example below. And by using an exponent or other fancy math in the buffer distance, you can have the space between lines get progressively larger as they get farther out to sea, if desired.
collect_geometries( # group results from below into a multipolygon
array_foreach(
# for an array from 1 to 15...
generate_series( 1, 15),
# ...make a buffer for each distance (pixels)
buffer($geometry, @element ^ 1.4)
)
)
In my style, I've also split that into a few sets of buffers, so that each group can have a thinner line style as they get farther from land.
Lakes
Lakes can be styled much the same as coastlines, based on negative distance buffers,but for hatching the process is a bit more complicated. That style looks best if it's underneath a land layer. With lake polygons, that means you need a separate polygon layer above for land—with lakes cut out of it. You could do this either by duplicating the lakes layer and styling it as inverted polygons—but bear in mind this will also cover everything including oceans if the coast is within the map extent—or by creating the "land minus lakes" layer by running the difference geoprocessing tool using the land and lakes layers.
If your map includes both lakes and ocean, putting it all together may require more than a couple of layer styles. The layers might look like this, for example, from bottom to top:
- Land styled for coastal effect (e.g. hatching)
- Lakes with a fill and shore effects
- Land (minus lakes) again with a fill style
- Lakes again styled with a lakeshore outline
- Land again with a coast outline
Stippling
I've seen stippling on water in both modern and old-timey maps, and it's pretty straightforward in QGIS with fill styles, but here are a couple of tips (these apply to any stipping, not just water!):
- You'd think that a random marker fill is perfect for this, but often I find random fills to be, well, too random, with conspicuous clusters and empty spaces. Instead I prefer a point pattern fill with some randomize pattern distances (half the pattern spacing, or so), ensuring more uniform coverage—which I think a human cartographer would strive for—while still appearing random.
- If you want stippling that fades out away from shore, use a series of rings with increasing distance from shore and fill them with patterns of decreasing density. That means several geometry generators that look something like this:
difference($geometry, buffer($geometry, -5))
,difference($geometry, buffer($geometry, -10))
,difference($geometry, buffer($geometry, -15))
. Note that these rings overlap each other, which I think is helpful for smoothing the transitions in density
Rivers
It's always tempting to throw blue lines on the map for rivers, but for reasons I'll explain in the next section, in many antique styles it's better to use your main "ink" color. That could be as simple as a black line, or you can convert river lines to polygons via buffers—and consider making nice tapered rivers using stroke weight attributes in a dataset like Natural Earth and/or the QGIS tapered buffer process. Then you can use styles similar to what I described for lakes or coastlines.
Making river mouths meet coastlines gracefully is a digital cartography challenge no matter the style, often requiring more geoprocessing and editing steps than I can explain here, so sadly I have no simple style file to offer. The image here is a quick attempt to make a river intersect a coast with my hatched style. It involved making a tapered buffer, applying the hatching style, editing its vertices to align the buffer to the coast, then adding a blue river line on top, edited to extend into the sea to properly mask the coastal effect.
Colors and fills
It's likely enough that your faux-antique map has no color, besides those of the ink and paper, but maybe you're making a fancy map for some wealthy merchant or monarch. The important thing to remember is that, prior to some early modern printing technologies, color would be added by hand even for printed maps. Some of the styles below are meant to suggest that color was added to the map separately, after printing.
Misaligned ink and color
As every 5 year old knows, it's hard to color inside the lines. Your hand slips or the color bleeds a bit. In QGIS styles, try to have line and color fill layers not quite match up with each other. Say you're showing countries with both an outline and fill. Instead of a simple style with both, use two different geometry generators with different randomization or other effects (e.g. wave_randomized
; see the beginning of this page).
Colors go on top
If color was the last thing added to a map, then, ideally, anything in your project with color besides the "paper" itself should be on top of the layer hierarchy. Practically speaking, assuming your "ink" color is pretty dark, it will be hard to tell the difference and it may not be worth the trouble of duplicating layers to separate fills and strokes. Whatever you choose, the only small tip here is to play with blending modes and transparency—on both color and "ink" layers—to suggest that the underlying ink's appearance is at least slightly affected by added color.
Tint bands
All my examples here have "tint bands" on countries—those colors that fade inward from the borders—which is not an outdated style at all! These are easy in QGIS with shapeburst fills, where you can specify two colors (or a color ramp) and the distance of the transition from one to the other. For the simple single color bands you see in my maps, they can either fade from one color to the same color with 0% opacity, or from the color to a background color.
As always, though, I don't want these bands to transition perfectly from color to background, at a perfect distance. The first thing to do is use wave_randomized
again to give the whole thing some wobble (both inside and outside the polygon), and the next is to add a style that affects both the distance and evenness of color.
- Above the shapeburst, add another geometry generator style with the expression
difference($geometry, buffer($geometry, -x))
wherex
is the same distance you set for the shapeburst. - Style with a random marker fill. Make sure "clip markers to polygon boundary" is not checked. Use density-based count; revisit this later to find the right density.
- Choose one (or more!) of the more complex shapes of simple marker, like hearts or stars. Give it the same color as the shapeburst (but maybe with transparency), and use expressions to randomize its size and rotation.
- On the marker (or possibly on the marker fill, but I've run into trouble there) enable draw effects and on the default Source change the effect type to blur. (Here again you'll want to try different values for strength etc.)
- For feature blend mode on this layer use something like multiply or burn.
The end result is little blobs of more intense color, both within the tint band and near its edge, which makes the color fill look less perfect and also nudges its distance outward here and there.
Combine color and texture
As color was not part of the printing process for many antique maps, it was also sometimes optional. If you were a fancy, wealthy person you might buy a colored version, but if you were a regular (well, also wealthy) person you might buy an uncolored version. This is to say, the map needed to work without color, so color should be in addition to lines, pattern fills, etc. I have no particular practical tip or style to show here; it's just something to keep in mind!
Downloads
Okay, now that you've suffered through my explanations, or simply skipped them, here's what you probably came for: styles to download and try for yourself! I hope that you can use these as a starting point for your own styles, editing the colors, sizes, etc. to suit your needs.
Two caveats:
- Certain aspects of a layer style, like layer opacity or blending mode, or whether something needs to be done as inverted polygons, are not part of the symbols themselves and you'd need to apply those yourself
- I've generally used pixels as the unit for everything, as these are intended for digital images exported straight from QGIS. (In fact I can make no promises that any of this will export correctly to, say, SVG.)
To use these styles in QGIS, import them with the style manager. See instructions for importing styles in QGIS documentation. After you've imported the symbols, they'll appear in a layer's symbology panel, where you can simply click one to apply it to your layer. Filter by the tag hand_drawn_styles to find them more easily.
Images and symbols
I've always done my best to imitate hand-drawn cartography without, well, drawing anything, hence all the convoluted vector styles I've gone through above. But there's no way around it: a hallmark of certain times and places in cartography is hand-drawn imagery and symbols. Ranges of mountains, towns, trees, animals, and more that represent the character of the land. Hacking these together from weird point symbols isn't going to cut it. We're going to need some drawings.
Alas... this is a topic for another day, as assembling image symbols and vector layers into a map that looks real is something I'm still learning.
For now, I'll point you to the work of author K. M. Alexander, whose incredible fantasy map brushes project provides a lot of image assets extracted from actual antique maps. Grab some PNGs and be sure to buy him a coffee!