I'm coloring countries based on variable v1 and I want to add geom_point to each of those countries and set geom size equal to my variable v2. However, when I add the geom_point, the geom_point for the USA does not appear and other points are scattered on the map.
Below is my script, as per other posts I've seen here.
ddf <- structure(list(Country = c("Brazil", "United States", "Sweden", "South Korea", "Senegal", "Pakistan", "Norway","New Zealand", "Mexico","India",
"Netherlands", "Denmark", "Czech Republic", "China"),
v1 = c(2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 9L, 1L, 3L, 1L, 4L), v2 = c(13, 3, 2, 2, 2, 11, 4, 15, 4, 4, 3, 12, 5, 20)),
.Names = c("Country", "v1", "v2"), row.names = c(2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 9L, 1L, 3L, 1L, 4L), class = "data.frame",
na.action = structure(2L, .Names = "2", class = "omit"))
data(wrld_simpl)
wrld_simpl#data$id <- wrld_simpl#data$NAME
wrld <- fortify(wrld_simpl, region="id")
wrld <- subset(wrld, id != "Antarctica")
SelectedCountries = subset(wrld, id %in% c("Brazil", "United States", "Sweden", "South Korea", "Senegal", "Pakistan", "Norway",
"New Zealand", "Mexico", "India",
"Netherlands", "Denmark", "Czech Republic", "China"))
CountryCenters <- aggregate(cbind(long, lat) ~ id, data = SelectedCountries,
FUN = function(x) mean(range(x)))
ddf = merge(ddf, CountryCenters, by.x = "Country", by.y = "id")
gg <- ggplot() +
geom_map(data=wrld, map=wrld, aes(map_id=id, x=long, y=lat), fill="grey90", size=0.25) +
geom_map(data=ddf, map=wrld, aes(map_id=Country, fill = v1), size=0.25) +
geom_point(data=ddf, aes(x=long, y=lat, size = v2), colour = "red")
gg
Any help would be appreciated!
It appears your centroid calculation has an issue with United States and New Zealand. One solution is to use sf for your geoprocessing and geom_sf for your plotting, like this:
library(maptools)
library(ggplot2)
library(sf)
data(wrld_simpl)
world <- st_as_sf(wrld_simpl)
# Define polygon features
poly_ddf <- st_as_sf(merge(ddf, world, by.x = "Country", by.y = "NAME"))
# Calculate centroids
# Centroid calc prefers projected data
# PICK A PROJECTION THAT MATCHES THE GOALS OF YOUR WORK
ddf_p <- st_transform(poly_ddf, crs = 6933)
centroids <- st_centroid(ddf_p)
#> Warning in st_centroid.sf(ddf_p): st_centroid assumes attributes are constant
#> over geometries of x
ggplot() +
geom_sf(data = world) +
geom_sf(data = poly_ddf, aes(fill = v1)) +
geom_sf(data = centroids, aes(size = v2), color = "red")
Related
I am plotting a collaborator network, where point size is scaled by the number of articles written in a country and lines between points represent collaborations, with line width and opacity scaled by number of collaborations. E.g.
library(tidyverse)
# data for lines
df_links <- structure(list(from = c("Argentina", "Argentina", "Canada",
"Austria", "Austria", "Italy", "Austria",
"Italy", "New Zealand"),
to = c("Canada", "Germany", "Germany", "Italy",
"New Zealand", "New Zealand", "Panama",
"Panama", "Panama"),
collabs = c(1L, 1L, 2L, 1L, 1L, 1L, 1L, 1L, 1L),
x = c(-64, -64, -106, 15, 15, 13, 15, 13, 175),
y = c(-38, -38, 56, 48, 48, 42, 48, 42, -41),
x_end = c(-106, 10, 10, 13, 175, 175, -81, -81, -81),
y_end = c(56, 51, 51, 42,-41, -41, 9, 9, 9)),
row.names = c(NA, -9L),
class = c("tbl_df", "tbl", "data.frame"))
# data for points
df_points <- structure(list(name = c("Argentina", "Austria", "Australia",
"Canada", "Germany", "France", "United Kingdom",
"Italy", "New Zealand", "Panama", "Venezuela"),
papers = c(1L, 1L, 1L, 22L, 3L, 2L, 1L, 1L, 2L, 1L, 1L),
x = c(-64, 15, 134, -106, 10, 2, -3, 13, 175, -81, -67),
y = c(-38, 48, -25, 56, 51, 46, 55, 42, -41, 9, 6)),
row.names = c(NA, -11L),
class = c("tbl_df", "tbl", "data.frame"))
#plot
ggplot() +
geom_curve(data = df_links,
aes(x = x, y = y,
xend = x_end,
yend = y_end,
size = collabs,
alpha = collabs),
curvature = 0.33) +
geom_point(data = df_points,
aes(x = x,
y = y,
size = papers),
colour = "red") +
coord_fixed(xlim = c(-150, 180), ylim = c(-55, 80)) +
theme_void()
My problem is with the legends. I want:
a legend named collabs which has line thickness and line opacity
a legend named papers which is point size
Instead I have papers and collabs (line size and point size) in one legend and opacity in a second. I think the issue is because I am using size inside aes for both geom_curve and geom_point?
E.g. I want something like this (edited in inkscape)
Any advice would be much appreciated!
This could be achieved via the ggnewscale package which allows for multiple scales and legends for the same aesthetic:
library(tidyverse)
library(ggforce)
library(ggnewscale)
ggplot() +
geom_curve(data = df_links,
aes(x = x, y = y,
xend = x_end,
yend = y_end,
size = collabs,
alpha = collabs),
curvature = 0.33) +
new_scale("size") +
geom_point(data = df_points,
aes(x = x,
y = y,
size = papers),
colour = "red") +
coord_fixed(xlim = c(-150, 180), ylim = c(-55, 80)) +
theme_void()
I'm trying to display the flags for each country. But it seems most of the flags are incorrect according to my code. I want them to be displayed only at the end of the geom line, add the flag to the legend, and make the flag more visible than how it displays now.
categ_top10EnergyModf %>%
mutate(country = tolower(country)) %>%
ggplot(aes(x= year, y=ggwt_hours, country = country, color=country, group=country))+
geom_line(size=1.5)+
geom_point(size=3)+
geom_flag(aes(country = factor(country), size = 4))+
scale_y_continuous(labels = scales::comma)+
facet_wrap(~type2,scale='free')+
labs(x= "Year", y= "Energy Production (GWh)", title = "Analysis of the Growth of Renewable/Non-Renewable Energy Production",
color="Country",fill = "country" )+
scale_color_discrete(name = "Country",
labels= c("Germany",
"Spain",
"France",
"Italy",
"Norway",
"Poland",
"Sweden",
"Turkey",
"Ukraine",
"United Kingdom")
)+
theme_grey() +
theme(plot.title = element_text(hjust = 0.5))
> dput(head(categ_top10EnergyModf))
structure(list(country = c("de", "de", "fr", "fr", "fr", "de"
), country_name = c("Germany", "Germany", "France", "France",
"France", "Germany"), type2 = c("Non-Renewable", "Non-Renewable",
"Non-Renewable", "Non-Renewable", "Non-Renewable", "Non-Renewable"
), year = structure(c(1L, 2L, 2L, 3L, 1L, 3L), .Label = c("2016",
"2017", "2018"), class = "factor"), ggwt_hours = c(471984, 449906,
448690.614, 447109.694, 445175.494, 393234.585)), row.names = c(NA,
-6L), groups = structure(list(country = c("de", "de", "de", "fr",
"fr", "fr"), country_name = c("Germany", "Germany", "Germany",
"France", "France", "France"), year = structure(c(1L, 2L, 3L,
1L, 2L, 3L), .Label = c("2016", "2017", "2018"), class = "factor"),
.rows = structure(list(1L, 2L, 6L, 5L, 3L, 4L), ptype = integer(0), class = c("vctrs_list_of",
"vctrs_vctr", "list"))), row.names = c(NA, 6L), class = c("tbl_df",
"tbl", "data.frame"), .drop = TRUE), class = c("grouped_df",
"tbl_df", "tbl", "data.frame"))
You could display a flag as the last point:
geom_flag(aes(x = ifelse(year == 2018, year, NA)), size = 4)
I also set the size not as an aesthetic.
You dont have to use factor(country). You defined your country aesthetic in ggplot already.
I apologize in advance, but I am really having a hard time trying to do a simple map plot in R using leaflet library. It might be the most basic question for such a simple problem, but I want to have a world map as an output with circles in those countries relative to n size. This being my input data:
country_groups <- structure(list(country_name = c("Australia", "Brazil", "Canada",
"China", "Germany", "India", "Japan", "Korea, Republic of", "Romania",
"Russian Federation", "Spain", "Taiwan, Province of China", "United Kingdom of Great Britain and Northern Ireland",
"United States of America"), latitude = c(47.516231, -14.235004,
56.130366, 35.86166, 51.165691, 20.593684, 36.204824, 35.907757,
45.943161, 61.52401, 40.463667, 23.69781, 55.378051, 37.09024
), longitude = c(14.550072, -51.92528, -106.346771, 104.195397,
10.451526, 78.96288, 138.252924, 127.766922, 24.96676, 105.318756,
-3.74922, 120.960515, -3.435973, -95.712891), n = c(2L, 1L, 1L,
541L, 1L, 6L, 3L, 6L, 1L, 3L, 1L, 3L, 1L, 56L)), row.names = c(NA,
-14L), class = "data.frame")
This is what I've tried but I get non-numeric argument for binary operator as an error.
country_groups$n <- as.integer(country_groups$n)
country_groups$longitude <- as.numeric(country_groups$longitude)
country_groups$latitude <- as.numeric(country_groups$latitude)
leaflet(country_groups)%>%
addCircles(lng = ~longitude, lat = ~latitude, weight = 1,
radius = n * 30, popup = ~country_name
)
And when I try to use as.numeric(n) inside the graph function, it drops this out Error in as.numeric(n) :
cannot coerce type 'closure' to vector of type 'double'
I try to show country data in a map using points in the map. Here the dataframe:
> dput(countries)
structure(list(country = structure(c(5L, 6L, 3L, 4L, 10L, 8L,
11L, 7L, 1L, 13L, 9L, 12L, 2L), .Label = c("Australia", "China",
"France", "Georgia", "India", "Ireland", "Malaysia", "Poland",
"Qatar", "Singapore", "South Africa", "Spain", "USA"), class = "factor"),
Latitude = c(20.593684, 53.142367, 46.227638, 32.165622,
1.352083, 51.919438, -30.559482, 4.210484, -25.274398, 37.09024,
25.354826, 40.463667, 35.86166), Longitude = c(78.96288,
-7.692054, 2.213749, -82.900075, 103.819836, 19.145136, 22.937506,
101.975766, 133.775136, -95.712891, 51.183884, -3.74922,
104.195397), Value = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
2L, 1L, 2L, 2L)), .Names = c("country", "Latitude", "Longitude",
"Value"), class = "data.frame", row.names = c(NA, -13L))
The code from here:
library(maps)
library(ggplot2)
base_world <- map_data("world")
map_data_coloured <-
base_world +
geom_point(data=countries,
aes(x=Longitude, y=Latitude, colour=Value), size=5, alpha=I(0.7))
But I receive this error:
Error in as.vector(x, mode) :
cannot coerce type 'environment' to vector of type 'any'
you need to pass the geom_polygon argument to map your base_world object
ggplot() +
geom_polygon(data=base_world, aes(x=long, y=lat, group=group)) +
geom_point(data=countries, aes(x=Longitude, y=Latitude, colour=Value), size=5, alpha=I(0.7))
I have this data frame:
dput(df2)
structure(list(Receiver = structure(c(4L, 3L, 2L, 1L), .Label = c("Australia",
"United Arab Emirates", "United Kingdom", "United States of America"
), class = "factor"), Sender = structure(c(1L, 1L, 1L, 1L), .Label = "United States of America", class = "factor")), .Names = c("Receiver",
"Sender"), row.names = c(NA, -4L), class = "data.frame")
I would like to draw and igraph as this:
library(igraph)
g<-graph.data.frame(df2)
plot(g, layout = layout.kamada.kawai, vertex.label = V(g)$name,
vertex.label.color= "red", edge.arrow.size=0.8,
edge.curved=T, edge.label.color="white",
edge.label.cex=0.8,vertex.shape="circle",edge.color="pink",
vertex.color="lightblue", asp=0, margin=0)
I would like to show vertex lables inside the verexes, without increasing the size of the vertexes. Any ideas how I can do this?
You can do something like this before the call plot:
V(g)$label.cex <- 0.5
But why not to use a shortcut of the names?
V(g)$name<-c('USA','UK','UAE','Aus')
dat <- structure(list(Receiver = structure(c(4L, 3L, 2L, 1L), .Label = c("Australia",
"United Arab \nEmirates", "United \nKingdom", "United \nStates of \nAmerica"
), class = "factor"), Sender = structure(c(1L, 1L, 1L, 1L), .Label = "United \nStates of \nAmerica", class = "factor")), .Names = c("Receiver",
"Sender"), row.names = c(NA, -4L), class = "data.frame")
library(igraph)
g<-graph.data.frame(dat)
V(g)$label.cex <- 0.6
plot(g, layout = layout.kamada.kawai, vertex.label = V(g)$name,
vertex.label.color= "red", edge.arrow.size=0.8,
edge.curved=T, edge.label.color="white",
edge.label.cex=0.8,vertex.shape="circle",edge.color="pink",
vertex.color="lightblue", asp=0, margin=0)
The following might help.
# size the network nodes based on their centrality
deg = igraph::degree(graph = g, v = V(g), mode = "all", loops = TRUE, normalized = FALSE);
igraph::V(g)$size = deg*3;
# set the label size based on the node size
igraph::V(g)$label.cex = igraph::V(g)$size/max(igraph::V(g)$size);