How to specify a single colour for rasters with tmap? - r

I would like to adjust the basic colour of a raster plotted with tmap, when there is only one value in the raster.
Here is a very simple reproducible example:
library(raster)
library(tmap)
a <- raster(matrix(sample(c(1, NA), 10000, replace = TRUE, prob = c(0.01, 0.99)), nr = 100, nc = 100, ))
tm_shape(a) +
tm_raster()
You can see that the default yellow colour is barely visible by a human eye. Hence, when drawing a map where you only have a few pixels, it is extremely difficult to locate where are the pixels with values.
Unfortunately, I was not able to change this colour after multiple attempts. I think this issue may be encountered by other users, thus if a simple answer arises here it might be very helpful.
Unsuccessful attempts:
tm_shape(a) +
tm_raster(col = "black")
tm_shape(a) +
tm_raster(palette = "RdBu")
Note: for this one, I expected either a Red or a Blue colour to show up. Not grey... I tried to adjust midpoints as well but nothing changed.
tm_shape(a) +
tm_raster() +
tm_layout(aes.color= c(fill = "black"))

Apparently, when you just specifiy col= it colors the whole raster in one color. So I guess you have to chose the layer where the points are on? And then provide a argument to palette= as explained in the documentation.
This is how I got it to work:
tm_shape(a) +
tm_raster(col = "layer", palette = "black")

Related

ggplot red-white gradient appears orange

I've created a heat map in ggplot and I'm using a default red to white scale_fill_gradient. When I plot the gradient however, it appears to have an orange tint. I was wondering if there was a way to edit how ggplot calculates the gradient so that I get pink intermediates so that it matches the other figures I'm making. Related to this graph, though I can post separately, I want to make my NA values have a striped pattern (rather than grey fill). I haven't found a way to do that in ggplot.
p <- ggplot(heat.data, aes(x = MutResFac, y = mutAA, fill = disruption)) +
geom_tile(color="grey50") +
scale_fill_gradient(name = "Disruption", limits = c(0,3),
labels = c("WT-like", "Mild", "Moderate", "Severe"),
low = "#FFFFFF", high = "#FF0000",
guide = "legend") +
theme(axis.text.x = element_text(size = 25, hjust = 1),
text = element_text(size = 25),
plot.title = element_text(hjust = 0.5)) +
coord_fixed() +
labs(x = "Position", y = "Mutant Amino Acid") +
ggtitle(title) +
scale_x_discrete(labels = wildTypeSeqLabels)
The simple answer as to why your middle range of colors from red to white comes out orange is that he in-between color value from #FF0000 and white is orange. The better practical color theory answer is that #FF0000 is a yellowish or orange-ish red, and not a blueish red, so the middle color will be orangeish. The most technical answer is explained in the technical documentation for the gradient color scale functions. The scale_..._gradient functions create the gradient based on keeping hue constant and varying chroma and luminance.
Options to fix scale
For this, I'll use an example dataset and plot with the base code here:
set.seed(1111)
df <- data.frame(x=1:10, y=rnorm(10,1,0.2), values=1:10)
p <- ggplot(df, aes(x,y, fill=values)) + geom_col(width=0.7)
You can consider one of the following:
select a more blue-ish red to start with:
p + scale_fill_gradient(low='#FFFFFF', high='#FE43AF')
Select your scale more discretely using scale_fill_gradientn:
pal <- c('#F8F6F6', '#F4AABC', '#E83D7D')
p + scale_fill_gradientn(colours = pal)
Incidentally, the function choose_color() from the colorspace package is a pretty useful little tool (requires shiny and shinyjs to be installed, as it's a shiny app) that can be helpful for choosing colors. This guide may also come in handy. scale_fill_gradientn and use of the choose_color() to set your palette gives you complete control, but it has a tendency to make the transition kind of odd: this is why I like the first gradient shown above vs. the second.
Patterned fills
Currently, there are no good, simple methods to create patterned fill in ggplot to my knowledge. Could be useful to ask a question, but the best seems to be this answer from SO. Not really too satisfactory, IMO, but it seems at the moment to be the best that can be done.

Dynamically align plots (custom ggplot2 legend for spatial maps) in R

I have a number of maps that I'm generating in R using the sf library and I would like to have a nice looking legend. Unfortunately, it seems that the standard legend for geom_sf() are these ugly looking boxes. The only SO post I could find on adjusting shapes in ggplot2 legends is here.
The here is to use guides(colour = guide_legend(override.aes = list(shape = 16))); however, this only seems to work for geom_point() and not for geom_sf().
Unless someone can suggest an alternative method for changing the shape of legend objects I will need to design a custom legend in Inkscape and align this along with various maps.
Here's a snippet of the code to show what I've tried already:
legend <- image_read_svg('https://svgshare.com/i/FDV.svg')
p1 <- ggplot() +
geom_sf(data=otherroads, size = .45, aes(color=SUFTYPABRV)) +
geom_sf(data=allroads, size = .55, aes(color=SUFTYPABRV)) +
scale_color_manual(values = plotcolors, guide = "legend") + theme_map() +
labs(title = "Sydney")
ggdraw() +
draw_plot(p1) +
draw_image(legend, width = 0.4, hjust = -0.75, vjust = 0.43)
Good legend location example
The output looks good in this case; however, this won't work for me because it requires manual tweaking for every plot.
What I would like is for the location of this legend to be dynamically placed according to the ggplot object, which depends upon the city I'm plotting.
Bad legend location example
The code (and data) in it's entirety can be cloned from github: https://github.com/moldach/map-help.git
This answer is not to adress the legend placement, but changing the legend icons. From your examples, I gather your data produces a legend that looks like this by default:
# example from the geom_sf help page
nc <- sf::st_read(system.file("shape/nc.shp", package = "sf"), quiet = TRUE)
# throwing in some random categorical data
nc$catvar <- sample(LETTERS[1:5], nrow(nc), replace = TRUE)
ggplot(nc) +
geom_sf(aes(colour = catvar))
Not too long ago, ggplot added the ability to set what legend shape you wanted by implicitly (via the ellipsis) adding the key_glyph argument to all layers, such as geoms and stats.
ggplot(nc) +
geom_sf(aes(colour = catvar), key_glyph = "timeseries")
You could use this, to set the glyph to points and then use the override.aes trick to get the shapes that you want.
ggplot(nc) +
geom_sf(aes(colour = catvar), key_glyph = "point") +
guides(colour = guide_legend(override.aes = list(size = 3, shape = c(15:19))))
It should work with all the regular legend placement tools that are already in ggplot. You might have to specify locations specific for the plot, but at least you won't have to export your legend to svg files first before adding them.

adjust a legend position in a barplot

I need to adjust the legend for the following barplot in a proper position somewhere outside the plot
COLORS=rainbow(18)
barplot(sort(task3_result$respondents_share,decreasing = TRUE), main="Share of respondents that mentioned brand among top 3 choices ", names.arg=task3_result$brand, col = COLORS)
legend("right", tolower(as.character(task3_result$brand)), yjust=1,col = COLORS, lty=c(1,1) )
Thanks guys, i couldn't solve the problem but i reached my goal using ggplot,
windows(width = 500, height= 700)
ggplot(data = task3_result, aes(x = factor(brand), y = respondents_share, fill = brand)) +
geom_bar(colour = 'black', stat = 'identity') + scale_fill_discrete(name = 'brands') + coord_flip()+
ggtitle('Share of respondents that mentioned brand among top 3 choices') +xlab("Brands") + ylab("Share of respondents")
As DatamineR pointed out, your code is not reproducible as-is (we don't have task3_result), but you can probably accomplish what you're talking about by playing with the x and y arguments to legend() - you can just set the x coordinate to something beyond the edges of the bars, for example. See the documentation: https://stat.ethz.ch/R-manual/R-devel/library/graphics/html/legend.html. Also note there the cex argument, because that legend might be bulkier than you want.
Note that you will have to specify a larger plot window in order to leave space for the legend; the relevant help file for that is plot.window: https://stat.ethz.ch/R-manual/R-devel/library/graphics/html/plot.window.html
Though you won't want to call plot.window directly - better to pass the relevant arguments to it through the barplot() function. If that doesn't make sense, I recommend you read up on R's base plotting package more generally.

how to create shifted color scale ggplot

I have a continous variable that I would like to map to the color of my points.
However the distribution of the variable is shifted tot the right.
So I thought I could use the quantiles to set the breaks but this doesn't seem to be working.
I think I don't understand the subtleties between all of the different variants of scale_colour_gradient.
ggplot(df, aes(x = LibPl, y = IntStd, color = totSmpInt)) +
geom_point(position = "jitter", alpha = 0.5) +
scale_colour_gradientn(colours = brewer.pal(n = 4, "RdYlBu"),
breaks = c(qn[1], qn[2], qn[3], qn[4], qn[5]))
As you can see from the color legend in the plot it doesn't really seem like the quantiles were used as break points.
I have read a few other similar posts, and tried variants, but none are working
Any help is appreciated.
Thanks,

cex equivalent in ggplot2

In my work, I frequently display scatterplots using text labels. That's meant a plot() command, followed by text(). I used cex to adjust to font size to what I wanted it very quickly.
I created a text scatterplot very quickly using qplot. But I can't adjust the size fast. Here's a silly code example:
data(state)
qplot(Income, Population,
data=as.data.frame(state.x77),
geom=c("smooth", "text"), method="lm",
label=state.abb)
Whereas in the old days I'd do:
plot(xlim=range(Income), ylim=range(Population),
data=state.x77, type="n")
text(Income, Population, state.abb,
data=state.x77, cex=.5)
If I wanted the text size halved from what I saw at the defaults (oh, and I'd have to do a linear regression manually and add abline() to get the regression line -- nice to do it all in one via ggplot2).
I know I can add a size adjustment with size, but it's not a relative size adjustment like I'm used to. Hadley tweeted me to say that size is measured in mm, which isn't fully intuitive to me. Since I often adjust the size of the plot, either in R or in LaTeX, an absolute scale isn't as useful to me.
I must be missing something really simple. What is it?
I think you are tyring to adjust the size of the text itself, not the x-axis, right?
Here's an approach using the ggplot() command.
ggplot(data = as.data.frame(state.x77), aes(x = Income, y = Population)) +
geom_smooth(method = "lm", se = FALSE) +
geom_text(aes(label = state.abb), size = 2.5)
qp <- qplot(Income, Population,data=as.data.frame(state.x77),
geom=c("smooth","text"),
method="lm",
label=state.abb)
qp + opts(axis.text.x = theme_text(size = 5))
I think Chase is probably right about wanting points as "labels":
qp <- qplot(Income, Population,data=as.data.frame(state.x77),
geom="smooth",method="lm",label=state.abb)
qp + geom_text(aes(label = state.abb), size = 2.5)
If "text" is given in the geom argument to qplot the default size is used and then gets overwritten (or underwritten as it were in this case). Give Chase the check. (Edit: should make size 2.5)
Edit2: Took digging but I found the way to get ggplot2 to cough up some of its defaults:
https://github.com/hadley/ggplot2/blob/master/R/geom-text.r
GeomText$new()$geom$default_aes
proto method (instantiated with ): function (.)
aes(colour = "black", size = 5, angle = 0, hjust = 0.5, vjust = 0.5,
alpha = 1)
There's got to be a better way....
qp <- qplot(Income, Population,data=as.data.frame(state.x77),
geom="smooth",method="lm",label=state.abb)
qp + geom_text(aes(label = state.abb, cex = 1.2))
Add cex inside aes will get what you want, as quoted from:
aes creates a list of unevaluated expressions. This function also performs partial name matching, converts color to colour, and old style R names to ggplot names (eg. pch to shape, cex to size)
http://docs.ggplot2.org/current/aes.html

Resources