Points changing sizes on ggplot geom_point and no legend? - r

Okay so here is my code for a base map:
gg <- ggmap(Peru) +
geom_map(data = peru.coast, map = peru.coast, aes(x = long, y = lat, map_id = region),
fill="gray", color="black") +
xlim(-86, -70) +
ylim(-20, -4) +
labs(x = "Longitude", y = "Latitude") +
coord_map()
I then add in towns I wish to name manually (wasn't sure how to do it using google maps as I only wanted these 4)
gg <- gg + geom_point(aes(x=-78.981885, y=-8.229354, size=3)) +
annotate("text", label='Salaverry', size=4, x=-77.2, y=-8.229354) +
geom_point(aes(x=-71.345838, y=-17.644347, size=3)) +
annotate("text", x=-70.545838, y=-17.644347, label = 'Ilo', size=4) +
geom_point(aes(x=-77.142375, y=-12.047544, size=3)) +
annotate("text", x=-75.9, y=-12.047544, label = 'Callao', size=4) +
geom_point(aes(x=-78.610677, y=-9.074166, size=3)) +
annotate("text", x=-76.9, y=-9.074166, label = 'Chimbote', size=4)
gg <- gg + guides(size=FALSE) #this removes the legend with the black dot and '3' on it
gg
I get this lovely map:
I then use this dataset to add datapoints, and I wish to make the points bigger or smaller according to 'n' abundance
Trip_Set sex Set.Lon Set.Lat n
119_1 hembra -81.09390 -9.32338 2
119_7 hembra -81.03117 -9.09622 1
161_3 macho -83.76533 -9.74533 5
193_8 hembra -81.00888 -9.00950 7
255_5 macho -80.14992 -8.64592 1
271_6 hembra -72.20233 -18.05117 6
271_6 macho -72.20233 -18.05117 7
328_7 hembra -78.66667 -12.91700 2
403_3 hembra -80.03037 -10.03900 1
428_2 hembra -83.01305 -8.74883 2
655_4 hembra -71.58363 -18.24882 1
using this code:
ggAB <- gg + geom_point(data=dframe4, aes(Set.Lon, Set.Lat, colour='red', size=n))
ggAB <- ggAB + theme(legend.title = element_text(colour="black", size=12, face="bold"))
ggAB <- ggAB + guides(colour=FALSE) #This removes the legend for the red colour
ggAB <- ggAB + scale_size(name='Sharks per line', range = c(5,9))
ggAB <- ggAB + theme(legend.key=element_rect(fill = NA)) #This removes the boxes around the points
ggAB
However, when I do this... I get this:
The datapoints are plotted great (phew!), but why does it make the points bigger for my town names? I can't seem to get it to just keep the abundance for my 'n' number datapoints... It also doesn't put an automatic legend on (as ggplot usually does), even when I try and put one in manually using the scale_discrete function.
I thought it might be something to do with the fact that I use gg + guides(size=FALSE) in the first part, but even when taking that out it doesn't work, but adds in an annoying legend for my town datapoints.
Any ideas?

The problem is that in the code where you add the towns, you have put the size inside the aes. Therefore it also gets transformed when you call scale_size(name='Sharks per line', range = c(5,9)). Just use size outside the aes:
gg <- gg + geom_point(aes(x=-78.981885, y=-8.229354), size=3) +
annotate("text", label='Salaverry', size=4, x=-77.2, y=-8.229354) +
geom_point(aes(x=-71.345838, y=-17.644347), size=3) +
annotate("text", x=-70.545838, y=-17.644347, label = 'Ilo', size=4) +
geom_point(aes(x=-77.142375, y=-12.047544), size=3) +
annotate("text", x=-75.9, y=-12.047544, label = 'Callao', size=4) +
geom_point(aes(x=-78.610677, y=-9.074166), size=3) +
annotate("text", x=-76.9, y=-9.074166, label = 'Chimbote', size=4)

In addition to #shadow's answer, I'd like to leave the following for the OP as supplementary information. This comes from the chat with the OP. If you want to avoid using annotate, you can use geocode in the ggmap package. Here, I added some from my answer to the previous question of the OP, and I combined/modified the OP's code. One change is that I used alpha so that you can see red/pink points in the ocean. One note is that the positions of the city names are not perfect; the further you go down south in the map, the more you see gaps between points and city names. This could be due to something to do with map projection. According to Wiki, googlemap is using something close to marcator, but not exact the same. This could be the reason. Some GIS experts here would be able to provide more information.
library(ggmap)
library(mapdata)
library(ggplot2)
# Get Peru map
Peru <- get_map(location = "Peru", zoom = 5, maptype="satellite")
# This is the layer I wish to put over the top
coast_map <- fortify(map("worldHires", fill = TRUE, plot = FALSE))
# Subset data for Peru
peru.coast <- subset(coast_map, region == "Peru")
### Get lon and lat using geocode() in the ggmap package and crate a data frame
cities <- c("Salaverry", "Chimbote", "Callao", "Ilo")
locations <- geocode(cities)
locations$city <- cities
locations2 <- transform(locations, lon2 = lon + 1.1) # This is for text position
ggmap(Peru) +
geom_map(data = peru.coast, map = peru.coast, aes(x = long, y = lat, map_id = region),
fill="gray", color="black") +
geom_point(data = locations2, aes(x = lon, y = lat, color = city), size = 4) +
geom_text(data = locations2, aes(x = lon2, y = lat, label = city), size = 3) +
scale_color_manual(values = rep(c("black"), times = 4)) +
geom_point(data = newdata, aes(Set.Lon, Set.Lat, size = n), colour = "red", alpha = 0.5) +
scale_size(name = "Sharks per line", range = c(5,9)) +
xlim(-86, -70) +
ylim(-20, -4) +
labs(x = "Longitude", y = "Latitude") +
coord_map("mercator") +
guides(colour=FALSE) +
theme(legend.key=element_rect(fill = NA))

Related

Is there a way to make this map more aesthetically pleasing by turning it into a choropleth?

Using this dataset: https://www.kaggle.com/datasets/syuzai/perth-house-prices. Is there a way of prettying it up (besides changing the colour scale) by turning it into a choropleth? Each individual point represents the price of a single house; the original data does organise the house prices by suburb level but the ozmaps package only gives boundaries up to LGA/district level.
library(ozmaps)
library(sf)
library(ggplot2)
ozmaps <- ozmaps::ozmap_states
p<- ggplot(ozmaps) +
geom_sf() +
geom_point(data = PerthReg2005, aes(x = LONGITUDE, y = LATITUDE, colour = PRICE),
size = 1, shape = 23,) +
coord_sf(xlim = c(115.5827,116.3432), ylim = c(-31.45745,-32.47298))
p + scale_colour_gradientn(colours = terrain.colors(10))

Difficulty combining geom_path and geom_text on ggplot map

I'm trying to use geom_path and geom_text to create a labeled map, but it is not going well. I can use each geom_path and geom_text separately, but I can't seem to get them to work together. I think it has something to do with geom_polygon, but I'm not sure what.
Here is how I prepared my shapefile for mapping:
meck.hiv <- as(meck.hiv, "Spatial")
meck.hiv#data$seq_id <- seq(1:nrow(meck.hiv#data)) #create unique id for each polygon
meck.hiv#data$id <- rownames(meck.hiv#data)
meck.hivdf <- fortify(meck.hiv) #fortify the data
zipcodedf <- merge(meck.hivdf, meck.hiv#data,
by = "id")# merge the "fortified" data with the data from our spatial object
cnames <- aggregate(cbind(long, lat) ~ zip, data=zipcodedf, FUN=function(x)mean(range(x))) #get the names of our zipcode (and center the coordinates for labels)
With this, I was able to get the following maps:
With labels, no paths:
p2 <- ggplot(data = zipcodedf, aes(x = long, y = lat)) +
geom_polygon(aes(group=group, fill=hispanic.dis)) +
geom_text(data=cnames, aes(long, lat, label = zip), size=3, fontface='bold', color="black")+ #This put in zip code names
scale_fill_brewer(breaks=c(1, 2, 3, 4, 5, 6, 7), labels=c("<5", "5-10", "11-15", "16-20", "21-25", "26-30", "31+"), palette="Reds",
na.value="darkgrey") +
coord_equal() +
theme(panel.background= element_rect(color="black")) +
theme(axis.title = element_blank(), axis.text = element_blank()) +
labs(title = "Hispanic Population by Zip Code", fill="Hispanic Population (% of Total)")
Resulting map with labels but no path
Paths, but no labels:
p3 <- ggplot(data = zipcodedf, aes(x = long, y = lat, group = group, fill = hispanic.dis)) +
geom_polygon() +
geom_path(color = "black", size = 0.2)+ #Oddly, use of geom_path with the above leads to weird stuff, but we can customize map lines without labels here
scale_fill_brewer(breaks=c(1, 2, 3, 4, 5, 6, 7), labels=c("<5", "5-10", "11-15", "16-20", "21-25", "26-30", "31+"), palette="Reds",
na.value="darkgrey") +
coord_equal() +
theme(panel.background=element_blank())+
theme(panel.background= element_rect(color="black")) +
theme(axis.title = element_blank(), axis.text = element_blank()) +
labs(title = "Hispanic Population by Zip Code", fill="Hispanic Population(% of Total)")
Resulting path with paths but no labels
Trying to combine
p4 <- ggplot(data = zipcodedf, aes(x = long, y = lat)) +
geom_polygon(aes(group=group, fill=hispanic.dis)) +
geom_text(data=cnames, aes(long, lat, label = zip), size=3, fontface='bold', color="black")+
geom_path(color = "black", size = 0.2)+ #Oddly, use of geom_path with the above leads to weird stuff, but we can customize map lines without labels here
scale_fill_brewer(breaks=c(1, 2, 3, 4, 5, 6, 7), labels=c("<5", "5-10", "11-15", "16-20", "21-25", "26-30", "31+"), palette="Reds",
na.value="darkgrey") +
coord_equal() +
theme(panel.background=element_blank())+
theme(panel.background= element_rect(color="black")) +
theme(axis.title = element_blank(), axis.text = element_blank()) +
labs(title = "Hispanic Population by Zip Code", fill="Hispanic Population(% of Total)")
Resulting screwed up plot with paths and labels
My trouble-shooting suggests that there's something about how geom_path is interacting with geom_polygon combined with ggplot(), but if I move all the instructions into geom_polygon, path doesn't show up at all (although a plot will generate), and if I move all the instructions into ggplot(), I get an error: "Error in FUN(X[[i]], ...): object 'group' not found" (below).
p5 <- ggplot(data = zipcodedf, aes(x = long, y = lat, group = group, fill = hispanic.dis)) +
geom_polygon() +
geom_path(color = "black", size = 0.2)+
geom_text(data=cnames, mapping=aes(x=long, y=lat))+#Oddly, use of geom_path with the above leads to weird stuff, but we can customize map lines without labels here
scale_fill_brewer(breaks=c(1, 2, 3, 4, 5, 6, 7), labels=c("<5", "5-10", "11-15", "16-20", "21-25", "26-30", "31+"), palette="Reds",
na.value="darkgrey") +
coord_equal() +
theme(panel.background=element_blank())+
theme(panel.background= element_rect(color="black")) +
theme(axis.title = element_blank(), axis.text = element_blank()) +
labs(title = "Hispanic Population by Zip Code", fill="Hispanic Population(% of Total)")
Any help is appreciated. Please let me know if I need to provide more information on anything.
{ggplot2}'s layering and inheritance can be confusing at times. I hope the following helps. Also check out whether you really want an "additional" geom_path() layer. It feels like you want to depict/highlight the county boundaries. Please also note the use of color for setting the boundary(line) color for a layer in the example.
I have to emulate your problem, as you did not provide a reproducible example. The initial code is to get me the map data for North Carolina. I construct a cnames dataframe for the county names. You should be able to apply this to your zip-code problem at the county level ... :)
library(dplyr)
library(ggplot)
library(maps) # helper package to get some map data
library(mapdata) # helper for some map data
counties <- map_data("county") %>% filter(region == "north carolina")
head(counties)
yields a data frame
long lat group order region subregion
1 -79.53800 35.84424 1857 54915 north carolina alamance
2 -79.54372 35.89008 1857 54916 north carolina alamance
3 -79.53800 35.98175 1857 54917 north carolina alamance
4 -79.52081 36.23385 1857 54918 north carolina alamance
5 -79.26298 36.23385 1857 54919 north carolina alamance
6 -79.27444 35.90726 1857 54920 north carolina alamance
Plotting the counties only (note: this would be your zip-code level).
To explain the principle of layer inheritance, I "set" all parameters in the layer call (i.e. geom_polygon()):
ggplot() +
geom_polygon(data = counties
, aes(x = long, y = lat, group = group) # aesthetic mapping
, color = "white" # fixed value for "line"
, fill = "lightblue") # fixed value for "fill"
If you now would add the geom_path() layer without giving it aesthetics, the plot will not change. Check that I set the color to blue and the linesize to 2 for demo purposes.
ggplot() +
geom_polygon(data = counties, aes(x = long, y = lat, group = group), colour = "white", fill = "lightblue") +
# ---------------- adding a layer with no aesthetics -----------
geom_path(color = "blue", size = 2) # ... no joy!
If you now move the data and aesthetics to ggplot() "base"-layer, also path will inherit the aesthetics. In this case path will draw the "outlines" of the of the grouped lat/lon positions. The layer order and color/size of geom_path() will "overwrite" the white coloured polygon lines.
ggplot(data = counties, aes(x = long, y = lat, group = group)) +
geom_polygon( colour = "white", fill = "lightblue") +
#------------ path layer with inherited "polygon" grouping
geom_path(color = "blue", size = 2)
Next let's create the (zipcodes :) ) aka text labels by averaging the lat/lon values for the different polygon segment points.
cnames <- counties %>%
group_by(subregion) %>%
summarise(long = mean(long), lat = mean(lat) # averaging for "mid"-point
)
> cnames
# A tibble: 100 x 3
subregion long lat
<chr> <dbl> <dbl>
1 alamance -79.4 36.0
2 alexander -81.2 35.9
3 alleghany -81.1 36.5
Now add a geom_text() layer to show the (zip codes) aka subregion names.
ggplot(data = counties, aes(x = long, y = lat, group = group)) +
geom_polygon( colour = "white", fill = "lightblue") +
geom_path(color = "blue", size = 2) +
# --------------- adding a geom_text() layer
geom_text(data = cnames, aes(x = long, y = lat), color = "green")
## ------- uuummmppfff throws an error
Error in FUN(X[[i]], ...) : object 'group' not found
This throws an error. So why is that? Implicitly the group aesthetic in the ggplot() call is understood by geom_polygon() and geom_path() ... however geom_text() has issues with.
Moving the group aesthetics to the polygon layer ...
ggplot(data = counties, aes(x = long, y = lat)) +
geom_polygon( aes(group=group), colour = "white", fill = "lightblue") +
geom_path(color = "blue", size = 2) +
geom_text(data = cnames, aes(x = long, y = lat, label = "subregion"), color = "green")
does the trick but corrupts the geom_path() layer.
What happens here is that the data points (i.e. lat/lon) are no longer grouped, and ggplot connects the end points in the order they appear in the counties data frame. These are the jig-jag lines you see across your plot.
Accordingly, you would need to put another aes(group=group) for the geom_path layer! ... assuming you really want the path for the outlines.
ggplot(data = counties, aes(x = long, y = lat)) +
geom_polygon( aes(group=group), colour = "white", fill = "lightblue") +
geom_path(aes(group=group), color = "blue", size = 2) +
geom_text(data = cnames, aes(x = long, y = lat, label = "subregion"), color = "green")
Obviously the color = "white" is overwritten by the geom_path() call. You may skip one or the other.
As a rule of thumb, ggplot works well with "long" data tables. The moment you add a 2nd (or more other data objects) make sure to track which aesthetics are required and/or inherited from one layer to the other. In your original example, you could move the geom_path() upwards to have the group = group aesthetics from the geom_polygon() call.
In case of doubt, always populate the data = ... and aes() for each layer before combining (and inheriting) parameters across layers.
Good luck!

why is my legend in ggplot2 in power bi backwards?

so i am running the r visual in power bi desktop, i put in my data set and written the code, but the legend shows up all messed up, can some one point out what i am doing wrong?
below is the code
x = dataset$yearnum
y = dataset$oddmean_interv
# y is red color
a = dataset$odd_ul95
b = dataset$odd_ll95
z = dataset$oddmean_base
# z is blue color
c = dataset$odd_ul95_base
d = dataset$odd_ll95_base
#converts column to vector
library(ggplot2)
p = ggplot(dataset, aes(x=x)) + geom_line(aes(y=y, color="blue")) + geom_line(aes(y=z, color="red")) +
ylim(0, 35) +
geom_errorbar(aes(ymin=b, ymax=a), width=0.2, position=position_dodge(0.05)) +
geom_errorbar(aes(ymin=d, ymax=c), width=0.2, position=position_dodge(0.05)) +
scale_colour_manual(values=c("red", "blue")) +
labs(x = "Year", y="Mean Overdose Per 100,000")
print(p)
here is what it shows
i am trying to get the red line to say oddmean_interv and the blue line to say oddmean_base.
any help is appreciated

Recieving error "Aesthetics must be either length 1 or the same as the data (9420): colour" in R

editeddf$MajorAF <- 1 - editeddf$MAF
pdf(paste(var, "alleleFrequencyplot.pdf", sep = ""))
world <- map_data("world")
p <- ggplot(world, aes(long, lat)) +
geom_map(map = world, aes(map_id = region),
fill = NA, color = "black") +
coord_quickmap()
print(p +
geom_scatterpie(aes(x = long, y = lat, group = 1, r = 5),
data = editeddf,
cols = c("MAF", "MajorAF"),
color = c("lightskyblue1", "palevioletred2"),
alpha = .8))
dev.off()
When running the above code in R, I get the following error:
Error: Aesthetics must be either length 1 or the same as the data (9420): colour
Not sure what the issue is, but when I remove the "geom_scatterpie" from the print statement, it prints a grey world map, which isn't exactly what I'm going for.
This might solve your color problem. Specify the colors for MAF and MajorAF seperatly in scale_fill_manual and not in geom_scatterplot. Then your pies will be colored blue and violet.
world <- map_data('world')
p <- ggplot(world, aes(long, lat)) +
geom_map(map=world, aes(map_id=region), fill=NA, color="black") +
coord_quickmap()
print(p + geom_scatterpie(aes(x=long, y=lat, group=1, r=5), data=editeddf, cols=c("MAF","MajorAF"), alpha=.8)+
scale_fill_manual(values=c("lightskyblue1","palevioletred2")))

Close polygon on ggmap (stat_contour)

I have recently started coding with R, so far it has been quite a journey with several obstacles on the road. Most of them I have been able to solve by searching the internet. However, now I am encountering a problem I am unable to fix. I found a sort of similair thread on stackoverflow, (How to fill in the contour fully using stat_contour), nevertheless it does not work in my situation, ggmap + ggplot seem unable to work together.
So, the problem is the following. I am studying whether the red light district in Amsterdam has an effect on local businesses. I do this by creating plot that shows business density in the city centre of Amsterdam. I have used this code to make it:
# Background map
geo <- geocode("Amsterdam", source="google")
lon <- geo$lon - .000
lat <- geo$lat + .000
map <- get_map(c(lon = lon, lat = lat), zoom=14,maptype = "satellite", color="color")
p <- ggmap(map) + theme(legend.position = c(1, 1), legend.justification = c(1,1)) +
xlab("Longitude") + ylab("Latitude")
# Map boundaries
#xmin = 4.86774509503174
#xmax = 4.92267673565674
#ymin = 52.3534171572766
#ymax = 52.386956071714
# RLD Map (so it can be read by ggplot2)
rldmap <- fortify(rld)
rld2map <- fortify(rld2)
natmap <- fortify(nat)
# Ticks
mid <- 250
mi <- 0
ma <- 500
r <- (ma-mi)/5
breaks = seq(mi,ma,r)
# Density
ncells <- 150
dens2000 <- kde2d(bedrijven2000$LONG, bedrijven2000$LAT, n = ncells)
densdf2000 <- data.frame(expand.grid(x = dens2000$x, y = dens2000$y), z = as.vector(dens2000$z))
densmap2000 <- p + geom_point(aes(x = x, y = y), data = coords2000, alpha = .5, size = 1) +
stat_contour(aes(x,y,z=z,fill = ..level..), data=densdf2000,geom="polygon", alpha=.3, inherit.aes = F) +
scale_fill_gradientn(name="density", breaks = breaks, colours=rev(brewer.pal(7,"Spectral"))) +
geom_polygon(aes(x=long, y=lat, group=group), fill='grey', size=.2,color='green', data=rldmap, alpha=0) +
geom_polygon(aes(x=long, y=lat, group=group), fill='grey', size=.2,color='green', data=rld2map, alpha=0) +
geom_polygon(aes(x=long, y=lat, group=group), fill='grey', size=.2,color='green', data=natmap, alpha=0) +
geom_point(aes(x = x, y = y), data = coords,color = 'yellow',alpha = 1, size = 1, shape=10) +
annotate('text', x=4.892, y=52.374, label = "Amsterdam", col="white") +
ggtitle("Business Density in Amsterdam year=2000")
plot(densmap2000)
Using this code provides the following output:
output density plot Amsterdam
The problem here is that the lines of the polygons that show the density stop when they are close to the border of the plot, this gives a disturbing image.
Therefore my question is, how can I make the polygons forget about the borders of the graph and make them continuous?
Managed to answer the question myself in the end, thanks to this thread: Truncated Density Polygons with ggmap
the answer lies in two parts:
1, edit extend and maprange in background map
ggmap(map, extent="normal", maprange=FALSE)
2, edit in code for plot, add:
coord_cartesian(xlim=c(min(4.86774509503174),max(4.92267673565674)),
ylim=c(min(52.3534171572766),max(52.386956071714))) +

Resources