benjann / geoplot

Stata module to draw maps
MIT License
28 stars 3 forks source link

Stata update #16

Closed ericmelse closed 7 months ago

ericmelse commented 9 months ago

Dear Ben, not an issue but a note (in case that you are not aware) that the current Stata update ( "04 Oct 2023") includes:

graph twoway now supports aspect ratios that provide common units in the x and y dimensions. Adding option aspectratio(1, units) creates a graph where one unit in the x dimension and one unit in the y dimension each take up the same distance on the plot. This is useful for plotting things such as latitude against longitude, which have common scaling of their units.

I suppose that this is relevant to geoplot.

Best, Eric

benjann commented 9 months ago

Oh wonderful, thanks for letting me know. I was asking for such a feature at the last UK Stata meeting, but I was not aware, that it has now already been introduced.

ericmelse commented 9 months ago

Yes, I thought so! By the way, I want to create geoplots for The Netherlands but I only need the boundary lines of the country as such and the (12) regions (provinces). So, I do not need rivers etc. Would you know where to get the most appropriate file for that?

benjann commented 9 months ago

I don't know. Eurostat? Statistics Netherlands?

benjann commented 8 months ago

Note that since the update from 09oct2023 geoplot now employs aspectratio(1, units) if used in Stata 18.

ericmelse commented 8 months ago

Dear Ben, after a substantial effort to get my hands on a set of shapefiles (shp & dbf) for The Netherlands, I finally succeeded. For this I had to resort to using a R package tmap that was created by Martijn Tennekes who is affiliated with Statistics Netherlands (CBS, see his Github here). Actually, for that package he worked with the author of a book on using R to create maps, see here for the second edition (which is work in progress, see his Github here). The little trick that I used was to export the shapefiles for The Netherlands from this R package, here I learned here about this trick (the map there is not as good as there are errors in it), using in R the following:

library(tmap)
data(NLD_prov)
new_file <- glue("NLD_prov.shp")
st_write(NLD_prov, new_file, append = FALSE)

which will put the set of shape related files in the current working folder of R. Using these I am now able to use them in Stata with your fine package, like:

* Setup
geoframe create regions NL_Data.dta, id(_ID) coord(xcoord ycoord) shpfile(NLD_prov_shp.dta)

* Create map
geoplot (area regions popultn, color(vlag, intensity(.5)) levels(17) ) ///
    (line regions, lw(*.3) lc(gs7)) , xsize(4.2) ysize(5) aspectratio(1, units) ///
    clegend(pos(5) ) /// clegend_suboption(color(gs5))) /// cuts(label) lc(gs5)) ///
    ztitle("Population", orientation(rvertical) s(*.6) c(gs5) m(l-0 r+0)) ///
    zscale(lc(gs8)) zlabel(, labc(gs5) labsize(*.8)) /// 
    ztick(, tlcolor(blue) tlwidth(*.5) tlength(*.5)) /// this is not used by geoplot but accepted
    compass(t(2) pos(2) size(3) xm(.2) ym(.2) c(gs9)) /// 
    sbar(units(km) ym(2) c(gs8) lab(size(*.5) c(gs5)))

which results in: Geoplot_Compass_test_units This is a fine result that certainly meets my data visualization needs.

ztick issue But note that the line of code controlling the color, width and length of the clegend axis is accepted by geoplotbut not processed: ztick(, tlcolor(blue) tlwidth(*.5) tlength(*.5)) I have tried many alternatives but, reading the help file instructions, I assume that it should work. Which might possibly mean that there is something amiss in the ado file.

compass labels issue Another rather minor issue is the current control of the compass size. I used here type(2) but my remark applies to each type. What happens when the size is changed from the default 5, like decreasing or increasing it, that then the size of the compass labels are not changing accordingly. As a result, in my example above, the point of the 'pointer' is moving inward the capital letter N (for North). Looking for perfection, as always, I suggest to include an option to control the size as well as the font type used for compass labels, like: compass(t(2) pos(2) size(3) fontsize(medium) font("Merriweather")) Or something similar. Time permitting, maybe you can implement this.

I attach the files should you want to replicate. Geoplot_NL.zip

benjann commented 8 months ago

compass labels issue: see suboption label() in compass(). For example, you could type compass(label(size(medium))); don't know how to change font though. Mayne I will add an option that allows you to define custom labels (so that the font can be specified). Possibly I will then change syntax to

label(["text" ...][, suboptions])

ztick issue: the option is processed, but ztick() is only for ticks without label, not for labeled ticks. Since no unlabeled ticks are printed, the option has no effect. What you probably want is zlabel(, tlcolor(blue) tlwidth(*.5) tlength(*.5)).

ericmelse commented 8 months ago

Thank you Ben, for your helping hand. I have continued with adjusting and cleaning my code as well as somewhat improving it. I did the following:

So, my revised code is:

local textclr ""58 144 254"*1.4"
geoplot (area regions popultn, color("58 144 254*.6" gs14 "168 144 8", ipolate(100, positions(0 .35 1)) ///
        intensity(.5)) lw(*.3) lc(gs7) cuts(350000(196875)3696875) ) ///
    , xsize(4.2) ysize(5) aspectratio(1, units) graphreg(fc(white) lc(white) ilc(white)) ///
    clegend(pos(5)) ztitle("Population", orientation(rvertical) s(*.7) c(`textclr')) ///
    zscale(lc(gs8) lw(*.6)) ///
    zlabel(, format(%9,0fc) labc(gs5) labsi(*.9) tlc(gs5) tlw(*.3) tl(*.5)) ///
    zmlabel(350000(196875)3696875, nolab tlc(gs5) tlw(*.3) tl(*4.35) tp(i)) ///
    compass(t(1) pos(2) si(2.3) xm(.2) ym(.2) c(gs9) lab(si(*.5) c(`textclr'))) /// 
    sbar(units(km) ym(2) c(gs8) lab(si(*.55) c(gs5)))

which results in: Geoplot_Compass_test_units5L

benjann commented 8 months ago

Hi Eric,

some comments:

Here's my reproduction of your graph (ignoring the font settings):

geoframe create regions NLD_prov
local textclr `""58 144 254"*1.4"'
geoplot ///
    (area regions popultn, lw(*.3) lc(gs7) ///
        cuts(350000(196875)3696875) /// => 17 bins
        color("58 144 254*.6" gs14 "168 144 8", ///
            ipolate(17, positions(0 .35 1)) intensity(.5))) ///
    , xsize(4.2) ysize(5) ///
      clegend(pos(5)) ///
      ztitle("Population", orientation(rvertical) s(*.7) c(`textclr')) ///
      zscale(lc(gs8) lw(*.6)) ///
      zlabel(, format(%9,0fc) labc(gs5) labsi(*.9) tlc(gs5) tlw(*.3) tl(*.5)) ///
      zmtick(350000(196875)3696875, tlc(gs5) tlw(*.3) tl(*4.35) tp(i)) ///
      compass(t(1) pos(2) si(2.3) xm(.2) ym(.2) c(gs9) ///
          lab(si(*.5) c(`textclr') gap(50))) /// 
      sbar(units(km) ym(2) c(gs8) lab(si(*.55) c(gs5)))

image

ben

benjann commented 8 months ago

By the way, I think you should apply

geoframe generate plevel

after loading the data because there seem to be some enclaves (e.g. in the Tilburg region). This makes sure that the enclaves will be treated as such. That is, type

geoframe create regions NLD_prov
geoframe generate plevel
local textclr `""58 144 254"*1.4"'
geoplot ...

ben

ericmelse commented 8 months ago

Right, Ben, many thanks for you suggestions to clean up my code. And, yes, indeed I also noticed the enclaves and worried what to do about them. Beside the Belgium enclaves, near Tilburg, there are 30 of them, see here), another 'enclosure' that got colored like the regional area of Zeeland in my previous examples is the so-called Veerse Meer. So, indeed, your suggestion to use:

geoframe create regions NLD_prov
geoframe generate plevel

worked perfectly (21 nested polygons were found): Geoplot_Compass_test_units6L My next step will be if I can add rivers to this map (I am looking for a shape file of those).

benjann commented 7 months ago

re compass labels: With the latest update it is now possible to define custom labels. The syntax is

compass(label(text(<labels>)))

Where <labels> are the labels to be used for north, south, east, and west. For example, you could type

compass(label(text("{bf:N}" "S" "E" "W")))

to print N in boldface. The different compass types have different default settings, but all of them now support labels in the same way. For example, the following would label north and south in compass type 3:

compass(type(3) label(text("{bf:N}" "S")))

ben