Small ggplot2 plots placed on coordinates on a ggmap - r

I would like to first use ggmap to plot a specific area with longitude and latitude as axes.
Then I would like to put small ggplot2 plots on the specific locations, given their longitude and latitude. These can be barplots with minimal theme.
My database may have the columns:
1. town
2. longitude
3. latitude
4. through 6. value A, B, C
I generate a plot (pseudocode)
p <- ggmap(coordinates)
and I have my minimal ggplot2 design
q<-ggplot2()+geom_bar(....)+ ... x-axis null y axis null minimal template
How to combine the two designs to have a ggmap with small minimal ggplot plots imposed on specific coordinates of the map?

Here's one I did using pie charts as points on a scatterplot. You can use the same concept to put barcharts on a map at specific lat/long coordinates.
R::ggplot2::geom_points: how to swap points with pie charts?
Needs further update. Some of the code used was abbreviated from another answer, which has since been deleted. If you find this answer via a search engine, drop a comment and I'll get around to fleshing it back out.
Updated:
Using mostly your adapted code from your answer, but I had to update a few lines.
p <- ggmap(Poland) + coord_quickmap(xlim = c(13, 25), ylim = c(48.8, 55.5), expand = F)
This change makes a better projection and eliminates the warnings about duplicated scales.
df.grobs <- df %>%
do(subplots = ggplot(., aes(1, value, fill = component)) +
geom_col(position = position_dodge(width = 1),
alpha = 0.75, colour = "white") +
geom_text(aes(label = round(value, 1), group = component),
position = position_dodge(width = 1),
size = 3) +
theme_void()+ guides(fill = F)) %>%
mutate(subgrobs = list(annotation_custom(ggplotGrob(subplots),
x = lon-0.5, y = lat-0.5,
xmax = lon+0.5, ymax = lat+0.5)))
Here I explicitly specified the dodge width for your geom_col so I could match it with geom_text. I used round(value, 1) for the label aesthetic, and it automatically inherits the x and y aesthetics from the subplots = ggplot(...) call. I also manually set the size to be quite small, so the labels would fit, but then I increased the overall bounding box for each subgrob, from 0.35 to 0.5 in each direction.
df.grobs %>%
{p +
.$subgrobs +
geom_text(data=df, aes(label = name), vjust = 3.5, nudge_x = 0.065, size=2) +
geom_col(data = df,
aes(Inf, Inf, fill = component),
colour = "white")}
The only change I made here was for the aesthetics of the "ghost" geom_col. When they were set to 0,0 they weren't plotted at all since that wasn't within the x and y limits. By using Inf,Inf they're plotted at the far upper right corner, which is enough to make them invisible, but still plotted for the legend.

Related

Overlay violin plots in r

I am trying to plot overlaying violin plots by condition within the same variable.
Var <- rnorm(100,50)
Cond <- rbinom(100, 1, 0.5)
df2 <- data.frame(Var,Cond)
ggplot(df2)+
aes(x=factor(Cond),y=Var, colour = Cond)+
geom_violin(alpha=0.3,position="identity")+
coord_flip()
So, where do I specify that I want them to overlap? Preferably, I want them to become more lighter when overlapping and darker colour when not so that their differences are clear. Any clues?
If you don't want them to have different (flipped) x-values, set x to a constant instead of x = factor(Cond). And if you want them filled in, set a fill aesthetic.
ggplot(df2)+
aes(x=0,y=Var, colour = Cond, fill = Cond)+
geom_violin(alpha=0.3,position="identity")+
coord_flip()
coord_flip isn't often needed anymore--since version 3.3.0 (released in early 2020) all geoms can point in either direction. I'd recommend simplifying as below for a similar result.
df2$Cond = factor(df2$Cond)
ggplot(df2) +
aes(y = 0, x = Var, colour = Cond, fill = Cond) +
geom_violin(alpha = 0.3, position = "identity")

Adding space *just* on right size of x-axis, color based on relative position, specify labels

I have a time series graph of 49 countries, and I'd like to do three things: (1) prevent the country label name from being cut off, (2) specify so that the coloring is based on the position in the graph rather than alphabetically, and (3) specify which countries I would like to label (49 labels in one graph is too many).
library(ggplot2)
library(directlabels)
library(zoo)
library(RColorBrewer)
library(viridis)
colourCount = length(unique(df$newCol))
getPalette = colorRampPalette(brewer.pal(11, "Paired"))
## Yearly Incorporation Rates
ggplot(df,aes(x=year2, y=total_count_th, group = newCol, color = newCol)) +
geom_line() +
geom_dl(aes(label = newCol),
method= list(dl.trans(x = x + 0.1),
"last.points", cex = 0.8)) +
scale_color_manual(values = getPalette(colourCount)) +
theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1),
legend.position = "none") +
labs(title = "Title",
x = "Year",
y = "Count")
This code works -- there are 49 lines, and each of them is labelled. But it just so happens that all the countries with the highest y-values have the same/similar colors (red/orange). So is there a way to specify the colors dynamically (maybe with scale_color_identity)? And how do I add space just on the right side of the labels? I found the expand = expand_scale, but it added space on both sides (though I did read that in the new version, it should be possible to do so.)
I am also fine defining a list of 49 manually-defined colors rather than using the color ramp.
One way to do it is to limit the x axis by adding something like
coord_cartesian(xlim = c(1,44), expand = TRUE)
In this case, I had 41 years of observations on the axis, so by specifying 44, I added space to the x-axis.
Thank you to #JonSpring for the help and getting me to the right answer!

Merging 2 Legends In a Specific way

I have a plot of my data that includes both a boxplot and a point plot (data from mtcars for illustration)
ggplot(mtcars,aes(x=factor(cyl), y=mpg), fill=factor(carb),shape=factor(vs))+
geom_boxplot(data=subset(mtcars,am==1),aes(x = factor(cyl), y = mpg,fill=factor(carb),shape=factor(vs)),outlier.shape = NA, alpha = 0.85, width = .65, colour = "BLACK") +
geom_point(data=subset(mtcars,am==1 & vs==1),aes(x = factor(cyl), y = mpg,fill=factor(carb),shape=factor(vs)),outlier.shape = NA,size=5,alpha=.4,shape=1, colour = "BLACK", position = position_dodge(width = 0.65))
my objective is for there
to be a single legend instead of two legends
that now shows all the colors associated with the fill (based on carb) and a single element which explains what the open circles correspond to (i.e. vs==1).
for that single element (that corresponds to geom_point) to display an open circle (corresponding to the open circle in the graph) and not boxplots as its currently showing.
any help will be greatly appreciated
Remove the shape aesthetic from geom_boxplot. Also, in general no need to specify color = "black", as this is the default for geom_boxplot (same for geom_point).
The version I was running online threw a warning regarding outlier.shape, so I have removed that.
Add shape as constant aesthetic to point and use scale_shape_manual to define your shape (use shape = 21 if you want a fill - your code suggests this, or shape = 1, if you don’t.). When you remove the legend title, the legends look fairly "merged".
However, Not sure what you exactly mean with "merged legend" . Mind showing a desired output?
library(ggplot2)
ggplot(mtcars,aes(x=factor(cyl), y=mpg), fill=factor(carb),shape=factor(vs))+
geom_boxplot(data=subset(mtcars,am==1), aes(x = factor(cyl), y = mpg, fill=factor(carb)), alpha = 0.85, width = .65) +
geom_point(data=subset(mtcars,am==1 & vs==1),aes(x = factor(cyl), y = mpg,fill=factor(carb), shape = "v = 1"), size=5, alpha=.4, position = position_dodge(width = 0.65)) +
scale_shape_manual(NULL, values = 21)

How do I correct the scale and order of the y axis in R on a barplot

Working with borehole data, attempting to plot the cross section with R. I'm rusty and am having trouble organizing the plot the way I want. From the image, my bar plot is not tracking with y axis values displaying the depth of the borehole, instead it tracks with the Layers (categorical data).
Very similar question was asked here but I could not get the code to work for my situation because my data is formatted differently.
Just to clarify, I want to put the y axis in increasing numerical order, starting at 0, with the categorical layer data mapped to the correct part of that depth.
my code:
g2 <- ggplot(data=df3,
mapping = aes(x=PointID,y=End_Depth,
fill=`Layer`)) +
geom_col(colour="black") +
labs(y="Depth")
The Data
The question you were pointing to contains a very good idea, to use geom_rect instead. You could do something like the following (comments in code)
library(tidyverse)
# just some fake data, similar to yours
foo <- data.frame(id = "id", layer = letters[1:6], depth = c(5,10,12,15,20,25))
foo2 <-
foo %>%
# using lag to create ymin, which is needed for geom_rect
# transforming id into integers so i can add / subtract some x for xmin/xmax
mutate( ymin = lag(depth, default = 0),
id_int = as.integer(factor(id)))
# I am turning off the legend and labelling the layers directly instead
# using geom_text
# this creates a "wrong" y axis title which I'm changing with labs(y = ... )
# the continuous x axis needs to be turned into a fake discrete axis by
# semi-manually setting the breaks and labels
ggplot(foo2) +
geom_rect(aes(xmin = id_int - .5, xmax = id_int +.5,
ymin = ymin, ymax = depth,
fill = layer), show.legend = FALSE) +
geom_text(aes(x = id_int, y = (depth + ymin)/2, label = layer)) +
scale_x_continuous(breaks = foo2$id_int, labels = foo2$id) +
labs(y = "depth")
Created on 2021-10-19 by the reprex package (v2.0.1)

Adding points to GGPLOT2 Histogram

I'm trying to produce a histogram that illustrates observed points(a sub-set) on a histogram of all observations. To make it meaningful, I need to color each point differently and place a legend on the plot. My problem is, I can't seem to get a scale to show up on the plot. Below is an example of what I've tried.
subset <-1:8
results = data.frame(x_data = rnorm(5000),TestID=1:5000)
m <- ggplot(results,aes(x=x_data))
m+stat_bin(aes(y=..density..))+
stat_density(colour="blue", fill=NA)+
geom_point(data = results[results$TestID %in% subset,],
aes(x = x_data, y = 0),
colour = as.factor(results$TestID[results$TestID %in% subset]),
size = 5)+
scale_colour_brewer(type="seq", palette=3)
Ideally, I'd like the points to be positioned on the density line(but I'm really unsure of how to make that work, so I'll settle to position them at y = 0). What I need most urgently is a legend which indicates the TestID that corresponds to each of the points in subset.
Thanks a lot to anyone who can help.
This addresses your second point - if you want a legend, you need to include that variable as an aesthetic and map it to a variable (colour in this case). So all you really need to do is move colour = as.factor(results$TestID[results$TestID %in% subset]) inside the call to aes() like so:
ggplot(results,aes(x=x_data)) +
stat_bin(aes(y=..density..))+
stat_density(colour="blue", fill=NA)+
geom_point(data = results[results$TestID %in% subset,],
aes(x = x_data,
y = 0,
colour = as.factor(results$TestID[results$TestID %in% subset])
),
size = 5) +
scale_colour_brewer("Fancy title", type="seq", palette=3)

Resources