I'm trying to create correct choropleth() map in R using GISTools package. I use choro.legend() to display my legend. However I can't create either correct legend placement, AND/OR I don't understand the role of fmt parameter in my choro.legend() function. It seems to me that fmt can decrease the space between my legend colors and description.

enter image description here

I found choro.legend help page that states fmtis "C style format for values stated in above choropleth class limits".

So this should just work with my classes values, not by the distance between legend items itself?

OR what is the human understandable meaning of this?

How can I decrease the distance between my choro.legend()'s items?

choropleth(my.shp, nc.lI[,1], shading = income.shade)
choro.legend(-12919698, 5314317,income.shade,title='My title',cex=0.8, bty = "n", fmt = "%0.1f")
  • I did a little digging/experimenting on this. I found this on C-style string formatting commands: stuff.mit.edu/afs/sipb/project/r-project/lib/R/library/base/… . But this doesn't seem to have any bearing on the distance between legend items. I do notice that in your code the title of the legend is 'My Title' but in your image there is not title on legend. Could there be an issue here? I doubt it but it's worth looking into. – haff Apr 23 '16 at 7:22
  • On further inspection, using a value of "%20.1f" produces a really wide legend (like yours) and a value of "%0.1f" produces one with the legend items much closer together. But you use a value of "%0.1f" and your items are spaced far apart. The only other thing that I could think of is potential white space padding the front of your values, but I don't know why you would have this. – haff Apr 23 '16 at 7:30

fmt has nothing to do with the spacing of legend items. For a detailed description of fmt please see Use C-style String Formatting Commands. Simply paste the following code snippet in your R console to see the differences (pi ~ 3.14):

sprintf("%f", pi)
sprintf("%.3f", pi)
sprintf("%1.0f", pi)
sprintf("%5.1f", pi)
sprintf("%05.1f", pi)
sprintf("%+f", pi)
sprintf("% f", pi)
sprintf("%-10f", pi) # left justified
sprintf("%e", pi)
sprintf("%E", pi)
sprintf("%g", pi)
sprintf("%g",   1e6 * pi) # -> exponential
sprintf("%.9g", 1e6 * pi) # -> "fixed"
sprintf("%G", 1e-6 * pi)

choro.legend() calls legend() internally. To reduce the horizontal spacing between legend items you should change the text.width parameter of the legend() function. Unfortunately choro.legend doesn't provide a parameter to set text.width externally rather computes it internally. I added a space_reduction parameter to the choro.legend and slightly modified the original function as follows:

choro.legend <- function (px, py, sh, under = "under", over = "over", between = "to", 
          fmt = "%g", cex = 1, space_reduction = 0, ...) 
  x = sh$breaks
  lx = length(x)
  if (lx < 3) 
    stop("break vector too short")
  res = character(lx + 1)
  res[1] = paste(under, sprintf(fmt, x[1]))
  for (i in 1:(lx - 1)) res[i + 1] <- paste(sprintf(fmt, x[i]), 
                                            between, sprintf(fmt, x[i + 1]))
  res[lx + 1] <- paste(over, sprintf(fmt, x[lx]))
  maxwidth <- max(strwidth(res)) - space_reduction
  temp <- legend(x = px, y = py, legend = rep(" ", length(res)), 
                 fill = sh$cols, text.width = maxwidth, cex = cex, ...)
  text(temp$rect$left + temp$rect$w, temp$text$y, res, pos = 2, 
       cex = cex)

Save this snippet in a R script file and source it. A reproducible code snippet would be like the following:



val <- blocks@data$POP1990
shade <- auto.shading(val)
choropleth(blocks, v= val, shade)
choro.legend(514000, 175000,shade,title='My Legend',cex=.8, bty = "n", fmt = "%0.0f",

Gradually diminish/increase the space_reduction parameter to achieve the desired result.

enter image description here

  • Tried to use the choro.legend function as outlined above, but regardless of the value I set for space_reduction, I get the following error message: Error in legend(x = px, y = py, legend = rep(" ", length(res)), fill = sh$cols, : 'text.width' must be numeric, >= 0 My function call looks like: choro.legend(-85.80,45.3,tneffort.shades,title='Trapnet lifts per year', cex=0.6,bty="n",fmt = "%0.0f",space_reduction=4000) Can anyone identify the source of the problem? – Darryl H Sep 20 '17 at 19:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.