benjann / geoplot

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

`clegend()` two issues #5

Closed asjadnaqvi closed 1 year ago

asjadnaqvi commented 1 year ago

clegend() is working really well! It has two possible minor issues:

  1. If there are missing data, clegend() is also including this.
geoplot ///
    (area nuts3_shp y_MEDAGEPOP, level(40) colors(CET L20, reverse) )  ///
    (line nuts1_shp, lc(white) lw(0.03) ) ///
    (line nuts0_shp, lc(black) lw(0.2)) ///
    , ///
    clegend(height(40) bplace(ne)) zlabel(#10) ///
    title("My Stata map with the geoplot package") ///
    note("Package = geoplot (Jann 2023)")
  1. If clegend(... bplace(XX)) is specified and legend(pos(X)) is also specified, then the latter overwrites the former.

I would also recommend replacing the bplace() with the more common pos() option. The version 18 placement() is too new and in the backend also refers to clock positions. Don't know why Stata would create two similar position options. If anything they should allow for more precise positioning up to one or two decimals e.g. pos(2.5).

geoplot_test2

benjann commented 1 year ago

You can specify clegend(nomissing) to omit the color for missing. But I see that I should probably make this the default if colorvar is continuous. The missing color has label "no data" by default, but if zlabel() is specified, this will be overwritten.

zlevel() is somewhat problematic also because if values are chosen that are outside the range that has been used to categorize colorvar, Stata will extend the range of the legend with additional colors. This is less of a problem at the bottom (as long as nomissing is specified or if there are no missings), because the first color will be used to fill in the extra range, but at the top Stata seems to invent additional colors that are not part of the chosen color scale. Don't know how to prevent (other than reminding users in the docu to make sure the zlabels lie within the original range).

benjann commented 1 year ago

clegend() no longer includes missing by default; type clegend(missing) to include missing.

asjadnaqvi commented 1 year ago

The missing is now dropped but a weird red color is added on top. The command is exactly the same as above. Just wanted to flag this:

geoplot_test2

benjann commented 1 year ago

Yes, this is because zlabel(#10) extends the range of the scale; at the bottom this is no problem because the additional space is filled with the first color; at the top Stata starts adding extra colors; I cannot prevent this. The only solution is to not use zlabels that are out of range. I currently do not parse user specified zlabel(), but I am thinking about disallowing zlabel() and providing an own option for the labels within clegend(), so I have control over things and can prevent axis labels that are out of range...

asjadnaqvi commented 1 year ago

This is now fixed, at least with the zlabel(#.) option:

geoplot ///
    (area nuts3 y_MEDAGEPOP, level(40) color(CET L20, reverse) )  ///
    (line nuts1, lc(white) lw(0.03) ) ///
    (line nuts0, lc(black) lw(0.2)) ///
    , ///
    clegend(height(40) bplace(ne)) zlabel(#10) 

geoplot_test2

benjann commented 1 year ago

I didn't make any changed here. It depends whether the automatic values generated by zlabel() are within bounds or not, which is hard to predict; but maybe I can just define thing so that the first color will go all the way down to a rather small number and similarly extend the last interval up, so that colors will always be ok no matter what values zlabel() picks.

asjadnaqvi commented 1 year ago

I am using the exact same code as above but this time the zlabel() seems to work. Can also test it more extensively.

benjann commented 1 year ago

weird. Maybe the reason is that geoplot now removes the "invisible" units (units with empty shapes) which might have slightly changed the range of the data, so that zlabel() now generates different labels.

benjann commented 1 year ago

I now revised the positioning options for legend() and clegend(). bplace() is no longer needed. position() sets the position and outside decides whether to place the legend inside or outside of the plotregion.

benjann commented 1 year ago

I close this issue since meanwhile also the problem with the weird color that sometimes appeared on top should be solved.