Blog

French-inspired mapping experiments - residential property prices map

4 min

That’s one more case for me to write about geography visualization. Geography has long fascinated me. And being a visual person, I’m naturally drawn to maps, infographics, and spatial data representation in general. This time the choice fell upon France. Apart from cartography itself, I’ve had a personal interest in the country for a long while, so it felt like a natural target for such a project.

What you see here is a map of residential property prices in France. The data is real: in early 2025 I got a chance to collect open-source real estate data and decided to visualize it. So this map is essentially a snapshot of the market at that moment. Go check it out!

How it’s done?

Technical

Again, this project sits somewhere between a technical and a visual realm. The technical side starts with the data itself. I aggregated real estate listings and calculated the main indicators by territory. The key metric here is median price per sq.m. It works better than average for housing data, since the market tends to include enough expensive and unusual properties to skew the picture too much otherwise.

Then came the geographic side. France turned out to be trickier than expected because of its complicated administrative structure. At least it’s been hard for me to grasp. Eventually I landed on three levels: regions, departments, postal codes. This felt like the best balance.

Regions provide a broad national overview and let you grasp the general market spread quickly. Departments work well as the middle layer: more detailed, but still clean enough visually. Postal codes add local detail and make the map much more practical from a real estate perspective. Actually I consider them as the layer doing actual heavy-lifting in terms of analysis.

The next question was the map type. For regions and departments I chose a 3D choropleth. It simply captures attention better and grabs attention at first glance. For the postal code level I switched to a more conventional 2D filled heatmap. It is more ordinary visually, but also cleaner. Once there are too many small areas, 3D starts adding clutter and visual noise. Labels become harder to manage, shapes compete with one another, and the view gets overloaded. I think this combination works quite naturally: expressive 3D for overview, simpler 2D for detail.

Color approach

Coloring is based on interpolation between a minimum and a maximum color. In simple terms, each map view has its own data range. There is a lowest and a highest price per sq.m. for that view, and the colors in between are calculated by linear interpolation. So on the regions level, the lightest color corresponds to the cheapest region and the darkest one to the most expensive region. On the departments level, the same principle applies again, but with department values. Postal codes follow the same idea as well.

However, there is an important nuance. The color scheme is not global across all levels. The same pair of colors is reused separately for each view. That means a relatively cheap region may appear light orange on the national map, and after clicking into it you’ll again see both light and dark oranges inside that region — because the scale has been recalculated for that view (departments). The legend updates accordingly.

It’s a somewhat controversial decision I’ve been thinking about for a while. A global scale would be more strict logically, since one exact color would always correspond to one exact price range everywhere. But it would also weaken local contrast quite a lot. So I opted for the latter.

There is one more detail here. On the regions and departments levels the polygons are extruded and lit, so the visible colors are quite a bit skewed by lighting. Because of that, those views are perceived not as pure flat colors, but as colored surfaces with light and shadow. On the postal code level the colors are shown directly.

Base map and labels

The base map is built on OpenStreetMap data, but edited by me. I wanted it to create a clear understanding of where we are, while staying visually quiet. A default basemap often distracts too much. And I’ll not deny that wanted to play around with basemap editing as well) So the task was to make the basemap supportive rather than dominant, and to give it enough depth against the main warm orange palette.

Labels were another challenge. I wanted to add city names on top of the rendered stuff, so that navigation would feel easier. But that immediately created conflicts with region names, which should remain visually primary. There are complicated ways to solve such overlapping automatically, but here I’ve opted not to overengineer and restrict the map pitch and adjust region label positions manually where needed. Just simple and practical.

Once more the link) Hope you find it informative and entertaining.