I have this code:
tm_shape(usa, bbox = bbox, projection = map.crs)+
tm_borders(col = "grey", lwd = 1) +
tm_fill(palette = "grey") +
tm_grid(x = c(-77,-75,-73,-71),
y = c(39,37,35),
labels.inside.frame = F,
labels.size = 1.1,
col = "white") +
tm_layout(outer.margins = c(.1,.03,.05,.05),
outer.bg.color = "white")+
tm_shape(sk.dat1,axes = T) +
tm_dots("DATELAND", palette = colo,
auto.palette.mapping=FALSE,
size = .5,
breaks = seq(2010,2017,
length.out =8),legend.show = T, alpha=.7) +
tm_layout(title = "Southern Kingfish Occurrence",
legend.show = T,
legend.position = c("right","bottom"),
legend.bg.color = "grey70",
legend.height = 2)
Which outputs this legend. How can I change the tmap input to only include single years with no commas?
This looks as a number format problem; your code is not exactly reproducible, so I can not make 100% sure, but I am fairly certain by the look.
To remedy try including this in your tm_layout call:
legend.format=list(fun=function(x) formatC(x, digits=0, format="d"))
By the way I wrote a short blog post on tmap legend formatting a couple months back (my problem were currency and percentage signs).
https://www.jla-data.net/eng/tmap-legend/
Related
Some ways to add labels on contour plots
# load packages
library('mgcv')
library('gratia') # draw(); smooth_estimates()
library('metR') # geom_contour2(); geom_text_contour()
library('ggplot2')
Simulate data using the example from Gavin Simpson's website: https://fromthebottomoftheheap.net/2018/10/23/introducing-gratia/
set.seed(1)
dat <- gamSim(2, n = 4000, dist = "normal", scale = 1, verbose = FALSE)
mod <- gam(y ~ s(x, z, k = 30), data = dat$data, method = "REML")
sm <- smooth_estimates(mod); sm
Plot using gratia with the number of contour lines automatically adjusted:
draw(mod) +
geom_text_contour(
aes(z = est), # 'est' from smooth_estimates(mod)
colour = "black", size = 4.5, fontface = "bold",
stroke = 0.3, stroke.colour = "white", # 'stroke' controls the width of stroke relative to the size of the text
skip = 0, # number of contours to skip
rotate = FALSE, # horizontal labeling; if TRUE, rotate text following the contour
label.placer = label_placer_fraction(frac = 0.5)) # 'frac = 0.5' places the label at equal distance from extremities. Try 'label.placer = label_placer_n(2)' to display two labels per contour line
However, contour lines and labeling do no longer match if we use e.g. 'n_contour = 10' within draw().
To allow this matching, use 'n_contour = 0' within draw(), define 'binwidth' within geom_contour2() and 'breaks' within geom_text_contour(), as follows.
Plot using gratia::draw with 'binwidth'-adjusted contour lines:
min(sm$est); max(sm$est) # find min() and max() for adjusting the 'est' z-scale
draw(mod, n_contour = 0) +
geom_contour2(aes(z = est), binwidth = 0.2) +
geom_text_contour(
aes(z = est), # 'est' from smooth_estimates(mod)
breaks = seq(-0.4, 0.4, by = 0.2), # 'breaks' must match with 'binwidth' above
colour = "black", size = 4.5, fontface = "bold",
stroke = 0.3, stroke.colour = "white", # 'stroke' controls the width of stroke relative to the size of the text
skip = 0, # number of contours to skip
rotate = FALSE, # horizontal labelling; if TRUE, rotate text following the contour
label.placer = label_placer_fraction(frac = 0.5)) # 'frac = 0.5' places the label at equal distance from contour lines' extremities. Try 'label.placer = label_placer_n(2)' to display two labels per contour line
Also possible to customize the graph directly with ggplot2:
ggplot(data = sm, aes(x = x, y = z, z = est)) +
geom_contour2(aes(z = est), binwidth = 0.1) +
geom_text_contour(
aes(z = est), # 'est' from smooth_estimates(mod)
breaks = seq(-0.4, 0.4, by = 0.1), # 'breaks' instead of 'bins' to not have too many decimals
colour = "black", size = 4.5, fontface = "bold",
stroke = 0.3, stroke.colour = "white", # 'stroke' controls the width of stroke relative to the size of the text
skip = 0, # number of contours to skip
rotate = FALSE, # horizontal labelling; if TRUE, rotate text following the contour
label.placer = label_placer_fraction(frac = 0.5)) # 'frac = 0.5' places the label at equal distance from contour lines' extremities. Try 'label.placer = label_placer_n(2)' to display two labels per contour line
You can use geom_textcontour from geomtextpath to obtain nicely placed labels without having to tweak lots of different parameters:
library(geomtextpath)
ggplot(sm, aes(x, z, z = est)) + geom_textcontour()
To use it within the gratia::draw framework, you can remove the existing contour from the plot first:
p <- draw(mod)
p$layers[[2]] <- NULL
p + geom_textcontour(aes(z = est), fontface = 'bold')
EDIT
To get a similar effect to the stroke parameter we can do:
library(ggfx)
p + with_outer_glow(geom_textcontour(aes(z = est), fontface = 'bold',
linetype = NA),
colour = 'white', expand = 3, sigma = 1) +
geom_textcontour(aes(z = est), fontface = 'bold', textcolour = NA)
I have created a wordcloud and, have used wordcloud() and ggplot(). I am unable to add the word frequencies to respective words in the cloud. I want the labels to appear in a single size and not in the size/weight of the associated word.
Can somebody help me add the labels? I have checked similar links:
How to display frequency in wordcloud
But I want the labels to be of standard size.
Sample code:
library(wordcloud)
wordcloud(BO$keywords, BO$bo, min.freq =1, scale=c(2.5,1), random.order = FALSE,
rot.per = 0,
colors = pal)+
geom_text_wordcloud_area(shape = "square", eccentricity = 2)+geom_text_repel(segment.size = 5, force = 1)
ggplot(BO, aes(label = keywords, size = bo), scale=c(6,5), min.freq = 1) +
geom_text_wordcloud(shape = "square", eccentricity = 2, area_corr=FALSE) +
scale_size_area(max_size = 6) +
theme_minimal()+
facet_wrap(~bo)+
scale_color_gradient(low = "lightblue", high = "darkblue")
I am using the R package GGPubr to make Boxplots. I really like the nice visuals that it provides but am having problems. Does anyone know how to increase the font size of the numbers on the axes, and the axis labels, and class labels? Also how do I set the mean values so that they only display 2 decimal places?
Here is the code that I'm using:
library("ggpubr")
mydata <- read.csv("C:\\temp\\ndvi.csv")
ggboxplot(mydata, x = "class", y = "NDVI",
color = "class",
order = c("Conifer", "Deciduous", "Grasslands"), ggtheme=theme_gray(),
ylab = "NDVI Value", xlab = "Land Cover Class",
add="mean",
font.label = list(size = 30, face = "bold"))+ stat_summary(fun.data
= function(x) data.frame(y=1, label = paste("Mean=",mean(x))), geom="text")
+theme(legend.position="none")
And the csv:
NDVI,class
0.25,Conifer
0.27,Conifer
0.29,Conifer
0.403,Deciduous
0.38,Deciduous
0.365,Deciduous
0.31983489,Grasslands
0.32005,Grasslands
0.328887766,Grasslands
I would prefer to achieve the desired effects above with GGPubr rather than boxplot() or ggplot/ggplot 2. Thanks.
Here is one option where we use round() to take care of the two decimal places and add another theme() to change the text size.
ggboxplot(mydata, x = "class", y = "NDVI",
color = "class",
order = c("Conifer", "Deciduous", "Grasslands"), ggtheme=theme_gray(),
ylab = "NDVI Value", xlab = "Land Cover Class",
add="mean",
font.label = list(size = 30, face = "bold")) +
# use round() and set y = .45
stat_summary(fun.data = function(x) data.frame(y=1, label = paste("Mean=", round(mean(x), 2))), geom="text") +
theme(legend.position="none") +
theme(text = element_text(size = 16)) # change text size of theme components
I'm having an issue with finding answers for a fairly simple question. I just need to move the axis titles (xlab and ylab) away from the axes. I haven't uploaded reproducible data since the files are large shapefiles, but I can upload it if needed (I figure it's a fairly straightforward answer). I have attached the code I've used so far as well as the map I'm struggling with:
LandUseMap <- tm_shape(LandUseshape, ylim = c(50.45, 50.68), xlim=c(-105,
-104.7), projection = "longlat") +
tm_fill("COVTYPE", title = "Land Cover Type",style="fixed",breaks=c(20,30,34,50,110,121,122,220,230),
labels=c("Water","Non-Vegetated Land","Developed","Shrubland","Grassland","Annual Cropland","Perennial Crops/Pasture","Broadleaf","No Data"),
palette=manualpal) +
tm_borders("grey") +
tm_legend(outside = TRUE, text.size = .65) +
tm_layout(frame = FALSE,asp =NA, outer.margins = c(0.05,0.1,0,0), inner.margins = c(0.05,0.05,0.01,0.05))+
tm_grid(y=c(50.45, 50.50, 50.55, 50.60, 50.65), x=c(-105.0,-104.9,-104.8,-104.7),labels.inside.frame = FALSE, col = "#00ff0000",
labels.size =0.8)+
tm_xlab("Longitude", size = 1)+
tm_ylab("Latitude", size = 1)+
tm_scale_bar(size = 1, position = c(0,0.8)) +
tm_compass(size=2.5,north = 0,position = c(0,0.9))
LandUseMap
Here's the map:
My map-making code generates a map based on census data and plots important points as a tm_dots() layer. What I'd like to be able to do is differentiate between the types of dots (e.g. if the location is "Informal" or "Commercial").
tm_shape(bristol) + tm_fill("population", palette = "YlOrRd",
auto.palette.mapping = TRUE,
title = "Bristol Population",
breaks = c(0,5,10,15,20,25), colorNA = "darkgrey") + tm_borders("grey25",alpha = 0.7, lwd = 0.1) +
tm_dots("n", size=0.1,col="green", shapeNA = NA, title = "Spaces") +
tm_legend(text.size=1,title.size=1.2,position=c("left","top")) +
tm_layout(legend.outside = TRUE, legend.outside.position = "bottom", title.snap.to.legend = TRUE)
What I'm looking for is essentially:
tm_dots("n", size=0.1,col=Classification, shapeNA = NA, title = "Spaces")
Adding several tm_dots() layers isn't an option. I also can't rename the dot legend, any advice on that too is appreciated.
Thanks for your help!
Solution
For future reference, I added offices to bristol via left_join, thus adding the Classification variable to the SpatialPolygonsDataFrame. I was having issues with it displaying NA values despite the showNA = NA parameter, but colorNA = NULL worked. Final line:
tm_dots(size=0.1,col="Classification", palette = "Set1", colorNA = NULL)
So bristol is a polygon shape (SpatialPolygonDataFrame or sf), and you want to plot dots in some polygons?
Normally, you would have a variable Offices, with two levels "Informal" and "Commercial". Then it's just tm_dots(size = 0.1, col = "Offices"). If you want to place two dots in one polygons because there are Informal and Commercial offices, then you can use your own approach (and use xmod and/or ymod for one group to prevent overlap), or create a SpatialPointsDataFrame or sf object with all offices, and a variable Offices with two levels as described above.
I figured it out, you need to have another tm_shape() for it to work. Still haven't got the title() to appear properly but one step at a time.
tm_shape(bristol) + tm_fill("population", palette = "YlOrRd", auto.palette.mapping = TRUE,
title = "Bristol Population",
breaks = c(0,5,10,15,20,25), colorNA = "darkgrey") + tm_borders("grey25",alpha = 0.7, lwd = 0.1) +
tm_dots("Informal_Offices", size=0.1,col="green", shapeNA = NA, title = "Informal Offices") +
tm_shape(bristol) + tm_dots("Commercial_Offices", size=0.1,col="white",shapeNA=NA, title="Commercial Offices") +
tm_legend(text.size=1,title.size=1.2,position=c("left","top")) +
tm_layout(legend.outside = TRUE, legend.outside.position = "bottom", title.snap.to.legend = TRUE)
Result