I am trying to plot a set of lat/long coordinates on a map of the USA using ggplot2, here is my code:
states <- map_data("state")
usamap <- ggplot(states, aes(long, lat, group=1)) +
geom_polygon(fill = "white", colour = "black") +
geom_point(data = data_masks2, aes(x = lng, y = lat), alpha = 1, size = 1) +
theme_cowplot()
However, when I plot usamap I am getting strange lines connecting some of the points (seen below), and I am unsure why. Why are these appearing, and how do I get rid of them?
Thanks in advance
There's a very helpful vignette available here for creating maps, but the issue is with your geom_polygon() line. You definitely need this (as it's the thing responsible for drawing your state lines), but you have the group= aesthetic wrong. You need to set group=group to correctly draw the lines:
ggplot(states, aes(long, lat, group=group)) +
geom_polygon(fill = "white", colour = "black")
If you use group=1 as you have, you get the lines:
ggplot(states, aes(long, lat, group=1)) +
geom_polygon(fill = "white", colour = "black")
Why does this happen? Well, it's how geom_polygon() (and ggplot in general) works. The group= aesthetic tells ggplot what "goes together" for a geom. In the case of geom_polygon(), it tells ggplot what collection of points need to be connected in order to draw a single polygon- which in this case is a single state. When you set group=1, you are assigning every point in the dataset to belong to the same polygon. Believe it or not, the map with the weird lines is actually composed of a single polygon, with points that are drawn in sequence as they are presented.
Have a look at your states dataset and you will see that there is states$group, which is specifically designed to allow you to group the points that belong to each state together. Hence, we arrive at the somewhat confusing statement: group=group. This means "Set the group= aesthetic to the value of the group column in states, or states$group."
for my PhD project, I'd like to show my sampling sites (coordinates) on a map showing them first on a map of NZ and then building a zoom in of the region (coordinates that I pick myself) to show the sampling sites in that specific region. I am very new to R and I am finding a bit frustrating.
I managed to build a map of NZ (code follows) but how can I add the data points on it and how can I create a zoom in of a certain region and adding data points on it as well??
NZ <- map_data("nz",xlim = c(166, 179), ylim = c(-48, -34))
ggplot() +
geom_path(aes(long, lat, group=group), data=NZ, color="black") +
coord_equal() +
scalebar(NZ, dist = 100, dist_unit = "km", st.size=3, height=0.01, model = 'WGS84', transform = TRUE)
Thanks to whoever will help me!!
For example:
library(tidyverse)
dunedin <- tibble(X=170.5, Y=-45 - 52/60, Text="Dunedin")
NZ <- map_data("nz",xlim = c(166, 179), ylim = c(-48, -34))
ggplot() +
geom_path(aes(long, lat, group=group), data=NZ, color="black") +
geom_point(data=dunedin, aes(x=X, y=Y), colour="blue") +
geom_label(data=dunedin, aes(x=X, y=Y, label=Text), colour="blue", nudge_x=1) +
coord_equal()
Incidentally, scalebar isn't part of ggplot2, so your example isn't self-contained. That's not a major issue here, but could be in another situation.
Trying to create a choropleth map showing state population also labeling capital cities. I had two data frame initially but was not able not add ggplot 1 to ggplot 2, so I combined two data frames together, part of the table looks like this:
basically trying to combines these two images together:
and
I've written
ggplot(spr, aes(long, lat)) + borders("state") + geom_point() +
coord_quickmap() +geom_label_repel(aes(label = city), size = 2) +
geom_polygon(aes(long, lat, group = capital, fill = pcls),color = "grey") +
coord_map("bonne", parameters=45) +ggthemes::theme_map() +
scale_fill_brewer(palette = "Reds")
but map looks off:
i think it's the polygon part is throwing me off but not sure what to do about it.
You'll need shapefiles, or at least have the borders known to map the data to.
In keeping with your question from the other day, you can still use state. scale_fill_brewer is designed for use with discrete variables. Use scale_fill_gradientn, specifying brewer.pal. Add the capitals layer in there as desired.
library(ggplot2)
library(usmap)
library(maps)
library(ggrepel)
library(ggthemes)
us <- map_data("state") # get the data to plot and map data to
data(statepop)
pops <- statepop
pops$full <- tolower(pops$full)
ggplot() + geom_map(data = us, map = us, aes(long, lat, map_id = region), fill = "#ffffff", color = "#ffffff", size = 0.15) +
geom_map(data = pops, map = us, aes(fill = pop_2015, map_id = full), size = 0.15) +
coord_map("bonne", parameters=45) +
scale_fill_gradientn(colors = brewer.pal(9, "Reds")) + #adjust the number as necessary
borders("state") +
ggthemes::theme_map()
Alright, so I'm struggling a bit in creating this map. The following code gives me this map, which is the map that I really want to use.
map(database= "world", ylim=c(15,90), xlim=c(-180,-24), fill = TRUE, projection = 'gilbert')
This is the code I used to save the map information.
map.dat <- map_data(map(database= "world", ylim=c(15,90), xlim=c(-180,-24), fill = TRUE, projection = 'gilbert'))
Now, when I run the following code, it gives me the error 'Error in eval(expr, envir, enclos) : object 'group' not found'. I'm not sure what that means.
ggplot(map.dat, aes(x=long, y=lat, group=group, fill=region)) +
geom_polygon() +
geom_point(data = basindf, aes(x = basindf$latitude, y = basindf$longitude)) +
theme(legend.position = "none")
I had set 'group = NULL' and 'fill = NULL' and that seems to allow me to plot, but it only displays this, which is not what I want. The map is gone!
What can I do to fix this? Also, I want to move away from the points and create lines. How would I be able to make lines based on a certain id?
EDIT: Seems that some of you needed basindf to troubleshoot. I've added the first 20 lines below.
"","id","year","month","date","basin","latitude","longitude","wind speed"
"1","1902276N14266",1902,"October",1902-10-03,"EP",-93.8,14,30
"2","1902276N14266",1902,"October",1902-10-03,"EP",-94,14.5,30
"3","1902276N14266",1902,"October",1902-10-03,"EP",-94.2,15,30
"4","1902276N14266",1902,"October",1902-10-03,"EP",-94.3,15.5,30
"5","1902276N14266",1902,"October",1902-10-04,"EP",-94.4,16,30
"6","1902276N14266",1902,"October",1902-10-04,"EP",-94.5,16.5,30
"7","1902276N14266",1902,"October",1902-10-04,"EP",-94.6,17,30
"8","1902276N14266",1902,"October",1902-10-04,"EP",-94.7,17.5,30
"9","1902276N14266",1902,"October",1902-10-05,"EP",-94.8,18,30
"10","1902276N14266",1902,"October",1902-10-05,"EP",-94.9,18.5,30
"11","1902276N14266",1902,"October",1902-10-05,"NA",-94.9,18.7,35
"12","1902276N14266",1902,"October",1902-10-05,"NA",-94.7,18.8,45
"13","1902276N14266",1902,"October",1902-10-06,"NA",-94.4,18.9,55
"14","1902276N14266",1902,"October",1902-10-06,"NA",-94,19.1,60
"15","1902276N14266",1902,"October",1902-10-06,"NA",-93.7,19.3,65
"16","1902276N14266",1902,"October",1902-10-06,"NA",-93.3,19.5,75
"17","1902276N14266",1902,"October",1902-10-07,"NA",-92.9,19.7,85
"18","1902276N14266",1902,"October",1902-10-07,"NA",-92.5,20,90
"19","1902276N14266",1902,"October",1902-10-07,"NA",-92,20.3,90
"20","1902276N14266",1902,"October",1902-10-07,"NA",-91.5,20.7,90
You have two main problems.
First, the error you are getting is because you are sepecufying aes() in the ggplot() call which means that those values inherit to all layers. That means it's trying to set a group= in the geom_point layer as well but you do not have groups for that layer. You can disable the inherited aesthetics with
ggplot(map.dat, aes(x=long, y=lat, group=group, fill=region)) +
geom_polygon() +
geom_point(data = basindf, aes(x = basindf$latitude, y = basindf$longitude), inherit.aes=FALSE) +
theme(legend.position = "none")
or you can sepecy the aes per layer
ggplot(map.dat) +
geom_polygon(aes(x=long, y=lat, group=group, fill=region)) +
geom_point(data = basindf, aes(x = basindf$latitude, y = basindf$longitude)) +
theme(legend.position = "none")
Your other problem is that you transformed your map data with a projection but not your point data.
You can transform your data with mapproj so they are both on the same scale
ggplot(map.dat) +
geom_polygon(aes(x=long, y=lat, group=group, fill=region)) +
geom_point(data = data.frame(mapproject(basindf$latitude, basindf$longitude, "gilbert")), aes(x = x, y = y)) +
theme(legend.position = "none")
This gives
The reason it was not working was because you set global aes parameters in the first call to aes, and ggplot2 was looking for group and region in the geom_points call to group and fill the points.
This technically works:
library(maps)
library(ggplot2)
ggplot() +
geom_polygon(data = map.dat, aes(x =long, y = lat, group = group, fill = region)) +
geom_point(data = basindf, aes(x = latitude, y = longitude)) +
theme(legend.position = "none")
You can see your map in the bottom right, very tiny. You want to rescale your map to lat/long, or your data to whatever you have in your map.
EDIT see the answer from #MrFlick for plot rescaling.
Thanks to help from some users on this site, I was able to get a nice map plot for some data using geom_point. (Get boundaries to come through on states) However, now I'm trying to clean it up as I have more years to plot and want to make sure the plot is working and providing good information. After some further research, it seems the geom_tile would actually be better for this as it would shy away from points and use a gradient.
The problem I'm running into is getting the code to work with geom_tile. It isn't plot anything and I'm not sure why.
Here's the dataset :
https://www.dropbox.com/s/0evuvrlm49ab9up/PRISM_1895_db.csv?dl=0
Here's the original code with geom_points :
PRISM_1895_db <- read.csv("/.../PRISM_1895_db.csv")
regions<- c("north dakota","south dakota","nebraska","kansas","oklahoma","texas","minnesota","iowa","missouri","arkansas", "illinois", "indiana", "wisconsin")
ggplot() +
geom_polygon(data=subset(map_data("state"), region %in% regions), aes(x=long, y=lat, group=group)) +
geom_point(data = PRISM_1895_db, aes(x = longitude, y = latitude, color = APPT), alpha = .5, size = 3.5) +
geom_polygon(data=subset(map_data("state"), region %in% regions), aes(x=long, y=lat, group=group), color="white", fill=NA)
And here is the code I've been trying, but none of the data is showing up.
ggplot() +
geom_polygon(data=subset(map_data("state"), region %in% regions), aes(x=long, y=lat, group=group)) +
geom_tile(data = PRISM_1895_db, aes(x = longitude, y = latitude, fill = APPT), alpha = 0.5, color = NA)
geom_polygon(data=subset(map_data("state"), region %in% regions), aes(x=long, y=lat, group=group), color="white", fill=NA)
geom_tile needs your x and y values to be sampled on an regular grid. It needs to be able to tile the surface in rectangles. So your data is irregularly sampled, it's not possible to divide up the raw data into a bunch of nice tiles.
One option is to use the stat_summary2d layer to divide your data into boxes and calculate the average APPT for all points in that box. This will allow you to create regular tiles. For example
ggplot() +
geom_polygon(data=subset(map_data("state"), region %in% regions), aes(x=long, y=lat, group=group)) +
stat_summary2d(data=PRISM_1895_db, aes(x = longitude, y = latitude, z = APPT)) +
geom_polygon(data=subset(map_data("state"), region %in% regions), aes(x=long, y=lat, group=group), color="white", fill=NA)
which produces
you can look at other options to control this bin sizes if you like. But as you can see it's "smoothing" out the data by taking averages inside bins.