benjann / geoplot

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

Cutout legend issue #22

Closed Monefield closed 5 months ago

Monefield commented 6 months ago

In one of the maps I use the "geoframe rclip"-command to make a cutout of an area (Works great!). But if this cutout doesn't contain points/polygons in all of the categories of the full map, the categories are shifted so they no longer align.

This code: geoplot (area kommuner num_areas_grp, select(!inlist(kom,400,411)) discrete) /// 1 (area cutout_capital num_areas_grp, discrete) /// 2 (area kommuner num_areas_grp, select(inlist(kom,400,411)) discrete) /// 3 (point omraader area_type, discrete) /// 4 AREAS, FULL MAP (point cutout_areas area_type, discrete) /// 5 AREAS, CUTOUT , legend(position(6) outside row(8) layout(- "{bf:Number of areas}" 1 | - "{bf:Area type}" 4)) /// zoom(2 5 7: 2, box(d) nocon position(32740000 6313000 nw)) /// Capital area zoom(3: 1, box(d) nocon pad(20) position(32740000 6309000 sw)) // Bornholm

produce this map: Cutout_issue1 You can see, that the two orange points near Copenhagen does not appear in the cutout (actually they do appear, but they are purple).

If I change line 6 in the code to use the legends from layer 5 (the cutout) instead of 4 (full map) the legend looks like this: Cutout_issue2 You can see, that type 3 is missing from the legend which causes Type 1 and 2 to have different colors in the full map compared to the cutout.

I made the workaround to add extra "fake" observations to the cutout data so that it contains all of the categories of the full map, but is there a way to avoid that workaround?

benjann commented 6 months ago

Specify option nodrop when applying geoframe rclip; this will leave all units in the data, even those whose shape is empty after clipping. geoplot then sees the same set of units for the full data and the clipped data and automatic categorization will be the same. Alternatively, make categories explicit by providing option cuts() in the relevant geoplot layers; assuming area_type is coded 1, 2,...,5 this would be cuts(1/5).

Monefield commented 6 months ago

I tried using the nodrop-option first:

frame omraader: geoframe rclip `limits', into(udklip_omraader) nodrop replace

But that got me this: Cutout_issue3

But if I use the cuts-option instead of the nodrop-option I get the map I was going for: Cutout_issue4

Thank you very much for the help :)

benjann commented 6 months ago

Ah, yes. The nodrop variant only works if the data structure is such that there is an attribute frame identifying the units and an associated shape frame containing the coordinates. In case of layer type point the coordinates are directly obtained from the attribute frame (i.e. the centroids; at least by default, in the latest version there is option shp to force point to obtain the coordinates from the shape frame if there is any).