# Scaling viz plots in GeoStats

**URL:** <https://discourse.julialang.org/t/scaling-viz-plots-in-geostats/112242>\
**Category:** New to Julia\
**Tags:** geostats\
**Created:** [March 28, 2024, 5:36pm UTC](https://discourse.julialang.org/t/scaling-viz-plots-in-geostats/112242 "2024-03-28T17:36:57Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![TimG](https://avatars.discourse-cdn.com/v4/letter/t/82dd89/32.png) [@TimG](https://discourse.julialang.org/u/TimG)\
**Post date:** [March 28, 2024, 5:36pm UTC](https://discourse.julialang.org/t/scaling-viz-plots-in-geostats/112242/1 "2024-03-28T17:36:57Z")

</div>

I am making chloropleth maps of different metropolitan areas in the UK.  
Here are two examples:

 ![display](https://global.discourse-cdn.com/julialang/original/3X/f/a/fa0bebc58710784c1d48768e7f3ee12213376504.png)  
 ![display](https://global.discourse-cdn.com/julialang/original/3X/f/3/f3f8b421f0a6e84eeaae1f8e62923c60bfe664f6.png)  
Now, Liverpool and London are very different in geographic size. Is there an easy way I can make these plots conform to the same (arbitrary) plot scale so that they are shown at the correct relative sizes? The geometry is specified on the same grid.  
Thanks!

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [March 28, 2024, 6:04pm UTC](https://discourse.julialang.org/t/scaling-viz-plots-in-geostats/112242/2 "2024-03-28T18:04:29Z")

</div>

As you don’t show ticks anyway, an easy option would be to center the data of both by subtracting the mean, and then linking both axes

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [March 28, 2024, 6:08pm UTC](https://discourse.julialang.org/t/scaling-viz-plots-in-geostats/112242/3 "2024-03-28T18:08:02Z")

</div>

Thanks for sharing these user questions @TimG , they are helping us improve the user experience.

@jules suggestion to link the axes may be all you need. Makie.jl should scale things automatically if it knows that the x and y axis of both subplots mean the same thing.

Alternatively, you can try to play with the zoom, fixing some option to a common value in both plots.

---

<div class="post-metadata">

**Author:** ![TimG](https://avatars.discourse-cdn.com/v4/letter/t/82dd89/32.png) [@TimG](https://discourse.julialang.org/u/TimG)\
**Post date:** [March 28, 2024, 6:18pm UTC](https://discourse.julialang.org/t/scaling-viz-plots-in-geostats/112242/4 "2024-03-28T18:18:49Z")

</div>

Thanks for this suggestion. I don’t immediately know how to do either of the things you suggest ( 🙄) but it can be something to look forward to after Easter!

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [March 28, 2024, 6:31pm UTC](https://discourse.julialang.org/t/scaling-viz-plots-in-geostats/112242/5 "2024-03-28T18:31:36Z")

</div>

@TimG you can call `Makie.linkaxes!(ax1, ax2)` to link axes `ax1` and `ax2` on the same figure. These axes are generated with the corresponding `viz` commands.

If that doesn’t solve the issue, or if you need to fix the scale in separate figures, then try to use some of the zoom options that Makie.jl provides. I believe that it is there somewhere in the docs. Couldn’t find it easily.

---

<div class="post-metadata">

**Author:** ![TimG](https://avatars.discourse-cdn.com/v4/letter/t/82dd89/32.png) [@TimG](https://discourse.julialang.org/u/TimG)\
**Post date:** [April 4, 2024, 8:58am UTC](https://discourse.julialang.org/t/scaling-viz-plots-in-geostats/112242/6 "2024-04-04T08:58:22Z")

</div>

For no particular reason, I wanted to keep the geometry data without transformation. Here, for the record, is what I did:

First, I found the boundingbox for each met area and find the min and max x, y values

```julia
function bbminmax(gt)
    bb = boundingbox(gt.geometry)
    minx, miny = coordinates(bb.min)[1:2]
    maxx, maxy = coordinates(bb.max)[1:2]
    return (minx, miny, maxx, maxy)
end

```

I could then find the biggest x-axis range and, separately, the biggest y-axis range of any of the met areas and position these symmetrically around the mean x, y for each map (I used a dataframe row for these parameters for each met area). I allowed 5% whitespace around the biggest dimension:

```julia
        for met in eachrow(df)
            met.minx, met.miny, met.maxx, met.maxy = bbminmax(gt |> Filter(row -> !ismissing(row.newLocalAuthority) && row.newLocalAuthority in met.boroughs))
        end
        df.xrange = df.maxx - df.minx
        df.yrange = df.maxy - df.miny
        xaxisrange = maximum(df.xrange) * 1.05
        yaxisrange = maximum(df.yrange) * 1.05
        df.xaxismin .= (df.minx .+ df.maxx .- xaxisrange) ./ 2.0
        df.xaxismax .= (df.minx .+ df.maxx .+ xaxisrange) ./ 2.0
        df.yaxismin .= (df.miny .+ df.maxy .- yaxisrange) ./ 2.0
        df.yaxismax .= (df.miny .+ df.maxy .+ yaxisrange) ./ 2.0

```

Then, in the viz! I was able to use axis limits for each plot:

```julia
function citymap(gt, df)
    fig = Mke.Figure()
    ax = []
    for (i, met) in enumerate(eachrow(df))
        longt = gt |> Filter(row -> !ismissing(row.newLocalAuthority) && row.newLocalAuthority in met.boroughs)
        col = log10.(longt.rat) # Can't currently have consistent colour scale across different plots
        push!(ax, Mke.Axis(fig[div(i - 1, 2)+1, mod(i - 1, 2)+1], title=met.metname, titlesize=10.0f0, limits=(met.xaxismin, met.xaxismax, met.yaxismin, met.yaxismax),
                    xlabel="BNG Easting", xlabelsize=8.0f0, xtickformat="{:.0f}", xticklabelsize=6.0f0,
                    ylabel="BNG Northing", ylabelsize=8.0f0, ytickformat="{:.0f}", yticklabelsize=6.0f0))
        viz!(ax[i], longt.geometry, color=col, colorscheme=:hawaii, colorrange=extrema(col), facetcolor="black", showfacets=true)
        ax[i].aspect = Mke.DataAspect()
    end
    Mke.Colorbar(fig[1:2, 3], limits=extrema(gt.rat), colormap="hawaii", scale=log10, tickformat="{:.1f}", ticklabelsize=8.0f0,
            label="Multiple of national average funding per capita", labelsize=10.0f0)
    # This common colorbar is not consistent with charts!
    Mke.display(fig)
end

```

This produces this set of maps:

 ![image](https://global.discourse-cdn.com/julialang/original/3X/3/6/36290ee26bf4840b8de504f266b90dc6872c788c.png)

This is great, and almost perfect!  
Major: The colour scale is not consistent between maps. The colours in each map are dependent on the map data. [The single colour bar is therefore a _lie_!](https://discourse.julialang.org/t/add-a-colorbar-to-a-viz-in-geostats/112193/10) (but this is _my_ lie, not GeoStat’s)  
Minor: I’d like to be able to have slightly thinner boundary lines. I can change the colour but not the weight of these lines, I think.

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [April 4, 2024, 9:26am UTC](https://discourse.julialang.org/t/scaling-viz-plots-in-geostats/112242/7 "2024-04-04T09:26:26Z")

</div>

That is great @TimG ! So your solution consisted of using the `min, max = coordinates.(extrema(boundingbox(geotable.geometry)))` to fix the axis limits in all subplots. That works too!

Regarding the colorbar and scale, we are already working on a fix based on your feedback. We created a new package [GitHub - JuliaGraphics/Colorfy.jl: Colorfy Julia objects](https://github.com/JuliaGraphics/Colorfy.jl) that converts any vector of values to colors from Colors.jl. This package will be registered in the following days, and we will refactor `viz` and the `viewer` with a new approach to colormaps and colorbars that is more flexible.

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [April 4, 2024, 9:27am UTC](https://discourse.julialang.org/t/scaling-viz-plots-in-geostats/112242/8 "2024-04-04T09:27:28Z")

</div>

Regarding the thickness of the boundaries, did you try the `segmentsize` option in `viz`?

---

<div class="post-metadata">

**Author:** ![TimG](https://avatars.discourse-cdn.com/v4/letter/t/82dd89/32.png) [@TimG](https://discourse.julialang.org/u/TimG)\
**Post date:** [April 4, 2024, 10:52am UTC](https://discourse.julialang.org/t/scaling-viz-plots-in-geostats/112242/9 "2024-04-04T10:52:06Z")

</div>

> [@juliohm](#):
>
> did you try the `segmentsize` option in `viz`?

I have now, and it works. Thanks!

My viz! now looks like this:

```julia
        viz!(ax[i], longt.geometry, color=col, colorscheme=:hawaii, colorrange=extrema(col), facetcolor="black", showfacets=true, segmentsize=0.3f0)

```

And the docs say:

`segmentsize` - size (or width) of segments  
`showfacets` - enable visualization of facets  
`facetcolor` - color of facets (e.g. edges)

My unfamiliarity with the nomenclature here meant I did not understand that segmentsize meant the line width of boundaries of facets! Presumably, segments and facets aren’t necessarily the same things?

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [April 4, 2024, 11:02am UTC](https://discourse.julialang.org/t/scaling-viz-plots-in-geostats/112242/10 "2024-04-04T11:02:08Z")

</div>

Facets are geometries with dimension - 1. In this case, polygons have dimension 2, and the facets are segments with dimension 2 - 1 = 1.

---

<div class="post-metadata">

**Author:** ![TimG](https://avatars.discourse-cdn.com/v4/letter/t/82dd89/32.png) [@TimG](https://discourse.julialang.org/u/TimG)\
**Post date:** [April 4, 2024, 11:10am UTC](https://discourse.julialang.org/t/scaling-viz-plots-in-geostats/112242/11 "2024-04-04T11:10:09Z")

</div>

> [@juliohm](#):
>
> So your solution consisted of using the `min, max = coordinates.(extrema(boundingbox(geotable.geometry)))` to fix the axis limits in all subplots

Yes. This is algorithmically very simple. My biggest challenge was to figure out how to access the data points. Having found `bb = boundingbox(gt.geometry)` easily, it took me more time that I’d like to admit to figure out `minx, miny = coordinates(bb.min)[1:2]`.  
Similarly, when I initially tried to find the x, y extrema manually, it took me a long while to get to this:

```julia
rx = extrema([coordinates(i)[1] for i in vertices(gt.geometry[borough])])
ry = extrema([coordinates(i)[2] for i in vertices(gt.geometry[borough])])

```

Inefficient, I know, (`boundingbox()` is considerably faster) but it worked!

Simple usage examples for stuff like this are very helpful in making the learning curve less steep!

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [April 4, 2024, 11:26am UTC](https://discourse.julialang.org/t/scaling-viz-plots-in-geostats/112242/12 "2024-04-04T11:26:44Z")

</div>

Appreciate if you can recommend these examples somewhere in our docs. Maybe we should add a tips and ticks section in the docs with random examples.

---

<div class="post-metadata">

**Author:** ![TimG](https://avatars.discourse-cdn.com/v4/letter/t/82dd89/32.png) [@TimG](https://discourse.julialang.org/u/TimG)\
**Post date:** [April 4, 2024, 11:28am UTC](https://discourse.julialang.org/t/scaling-viz-plots-in-geostats/112242/13 "2024-04-04T11:28:32Z")

</div>

Happy to have a go at this if you tell me where/how.  
Remember, I’m still learning!

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [April 4, 2024, 12:31pm UTC](https://discourse.julialang.org/t/scaling-viz-plots-in-geostats/112242/14 "2024-04-04T12:31:45Z")

</div>

That is a nice contribution! Are you familiar with Documenter.jl in Julia?

You can create a tipstricks.md file [here](https://github.com/JuliaEarth/GeoStats.jl/tree/master/docs/src) similar to our quickstart.md, and then list it in the docs/make.jl file. We can take it from there. 🙂

---

<div class="post-metadata">

**Author:** ![asinghvi17](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/asinghvi17/32/8272_2.png) [@asinghvi17](https://discourse.julialang.org/u/asinghvi17)\
**Post date:** [April 4, 2024, 4:06pm UTC](https://discourse.julialang.org/t/scaling-viz-plots-in-geostats/112242/15 "2024-04-04T16:06:58Z")

</div>

For the common colorbar, you can always set the colorranges of the plots afterwards 🙂

```julia
import Makie
function unify_colorranges!(plots...)
    cranges = Makie.to_value.(getproperty.(plots, :colorrange))
    setproperty!.(plots, :colorrange, ((minimum(first.(cranges)), maximum(last.(cranges))),))
end

```

then call `unify_colorranges!` on the result of all your `viz!` calls. You can accumulate those the same way you accumulated the axes in `ax`.

---

<div class="post-metadata">

**Author:** ![TimG](https://avatars.discourse-cdn.com/v4/letter/t/82dd89/32.png) [@TimG](https://discourse.julialang.org/u/TimG)\
**Post date:** [April 4, 2024, 5:48pm UTC](https://discourse.julialang.org/t/scaling-viz-plots-in-geostats/112242/16 "2024-04-04T17:48:37Z")

</div>

This sounds like a great option.  
I want my colorrange to be calculated nationally, so I don’t need to look-up what the range is on each map, I can just overwrite it.

So I accumulate my `viz!` calls as:

```julia
vis = []
push!(vis, viz!(ax[i], longt.geometry, color=col, colorscheme=:hawaii, #=colorrange=extrema(col),=# facetcolor="black", showfacets=true, segmentsize=0.3f0))

```

I can then simply set

```julia
setproperty!.(vis, :colorrange, (extrema(log10.(gt.rat)),))

```

But now, how do I get the updated `viz!` maps into the `fig`?

Because just doing the above and then

```julia
Mke.display(fig)

```

results in a plot where each of the maps still has the original colours.

---

<div class="post-metadata">

**Author:** ![TimG](https://avatars.discourse-cdn.com/v4/letter/t/82dd89/32.png) [@TimG](https://discourse.julialang.org/u/TimG)\
**Post date:** [April 4, 2024, 5:55pm UTC](https://discourse.julialang.org/t/scaling-viz-plots-in-geostats/112242/17 "2024-04-04T17:55:34Z")

</div>

> [@juliohm](#):
>
> That is a nice contribution! Are you familiar with [Documenter.jl](https://juliahub.com/ui/Packages/General/Documenter) in Julia?
> 
> You can create a tipstricks.md file [here](https://github.com/JuliaEarth/GeoStats.jl/tree/master/docs/src) similar to our quickstart.md, and then list it in the [docs/make.jl](https://github.com/docs/make.jl) file. We can take it from there. 🙂

All completely new to me, I’m afraid.

I have something for you to look at and judge suitability. If hopeless, that’s fine. If not, maybe I can extend. But I need to share first. In GitHub it says I need to fork before I can propose a change. Is that the right thing to do…? 🤷‍♂️

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [April 4, 2024, 7:06pm UTC](https://discourse.julialang.org/t/scaling-viz-plots-in-geostats/112242/18 "2024-04-04T19:06:05Z")

</div>

> [@TimG](#):
>
> I have something for you to look at and judge suitability. If hopeless, that’s fine. If not, maybe I can extend. But I need to share first. In GitHub it says I need to fork before I can propose a change. Is that the right thing to do…? 🤷‍♂️

That is lovely. Please feel free to proceed. You fork the repo, edit the files and then submit a PR. See the contribution page for more info:

[https://juliaearth.github.io/GeoStatsDocs/stable/contributing.html](https://juliaearth.github.io/GeoStatsDocs/stable/contributing.html)

---

<div class="post-metadata">

**Author:** ![TimG](https://avatars.discourse-cdn.com/v4/letter/t/82dd89/32.png) [@TimG](https://discourse.julialang.org/u/TimG)\
**Post date:** [April 8, 2024, 8:12am UTC](https://discourse.julialang.org/t/scaling-viz-plots-in-geostats/112242/19 "2024-04-08T08:12:52Z")

</div>

> [@TimG](#):
>
> Major: The colour scale is not consistent between maps. The colours in each map are dependent on the map data. [The single colour bar is therefore a _lie_!](https://discourse.julialang.org/t/add-a-colorbar-to-a-viz-in-geostats/112193/10) (but this is _my_ lie, not GeoStat’s)

I have now found an [easy fix](https://discourse.julialang.org/t/add-a-colorbar-to-a-viz-in-geostats/112193/14) for this.
