ofelinda
ofelinda

Reputation: 1

ggplot - How to conditional color points in a map

So I have a data frame that has all the information from climate_extremes.RData along with the city and country name, no. population, latitude , longitude (from packages 'maps', data (world.cities) ) All of it it's joined, everything good.

In the first bit of code I wanted to have a world map with all the cities as dots. It worked.

My problem comes on the second part where I had tried to have every city dot coloured according by the wsdi values. At the same time the city has to be grouped based on scenario and year.

I do not really understand why I get this error when everything is specified in the code? I am quite new to R and trying to learn it through a platform but ... yeah.

Error in check_aesthetics(): ! Aesthetics must be either length 1 or the same as the data (939): x and y

`

map <- ggplot() + borders("world",fill="white",colour="gray80") + geom_point(aes(x=data_frame1$lon, y=data_frame1$lat), colour ="blue", size = 0.003) 


data_frame1 %>% group_by(city,wsdi) %>% filter(scenario == 'historical' & year == '1997') %>%
  select(city) %>%
  ggplot() + borders("world",fill="white",colour="gray80") +
  geom_point(aes(x=lon, y=lat), fill = wsdi , size = 0.03)

`

Thank you in advance!

I've also tried with color rather than fill, and tried to specify from where it is (like data_frame1&wsdi), same error. Also wsdi is a column with numerical values and it has a corespondent to every city.

Upvotes: 0

Views: 976

Answers (1)

Ray
Ray

Reputation: 2268

The praise goes to @Isaiah for pointing out the answer. You need to understand how {ggplot2} uses layers and maps variable to aesthetics.

Please also note that {ggplot2} works nicely with data frames. So you do not need to assign the vectors to the x- and y-aesthetics.

data

We simulate your wsdi (climate data) by assigning random integers to your data frame.

0. data frame operations

Working with data frames: You group and filter, then pull the variable city.
Please note that with ... %>% select(city) you truncate your data frame to this "single" column.

Note2: think about "ungrouping" data frames once you have done your calculations. This might hurt you with other operations.

library(dplyr) # data crunching

set.seed(666)                                     # set seed to replicate random draws
df1 <- maps::world.cities %>% 
  mutate(wsdi = sample(1:10                       #simulated values of climate
                       , nrow(maps::world.cities) #length of vector to input
                       , replace = TRUE)          #identical values are possible
   ) 

head(df1)
                name country.etc   pop   lat  long capital wsdi
1 'Abasan al-Jadidah   Palestine  5629 31.31 34.34       0    5
2 'Abasan al-Kabirah   Palestine 18999 31.32 34.35       0    9
3       'Abdul Hakim    Pakistan 47788 30.55 72.11       0    1
4 'Abdullah-as-Salam      Kuwait 21817 29.36 47.98       0    2
5              'Abud   Palestine  2456 32.03 35.07       0    3
6            'Abwein   Palestine  3434 32.03 35.20       0    5

1. Fixed colors - your first example that worked

ggplot() + 
 borders("world", fill = "white", colour = "grey80") +    # specific ggplot layer for world maps
 geom_point( data = df1               # our data frame for this layer
#-------- with aesthetic mapping you assign "varying" values to graph properties
            , aes(x = long, y = lat)  # mapping of variables to aesthetics (here: x- and y-position on our graph)
#-------- then you can assign "fixed" (aka static) properties
            , colour = "blue"         # make all points "blue"
            , size = 0.003            # plot all points with size 0.003
           )

2. Have color varying with value of wsdi variable

As mentioned by @Isaiah, you want to "map" the point color to a "changing" variable. Thus, we can no longer use a "fixed" assignment. This is one of the characteristics of the grammar or graphics.

We created the wsdi variable in our data frame mutate above.

As a reminder ggplot works well with data frames. The simulated df1 contains the desired wsdi variable/column. Thus we can work with this data frame.

ggplot() + 
  borders("world", fill = "white", colour = "grey80") + 
  geom_point(data = df1
  #-------- with aesthetic mappings ... now we add varying color! -------
            , aes(x = long, y = lat
                   , colour = wsdi     # color property mapped to variable
                  )
  #------- any fixed properties of our graph -----------------------------
            , size = 0.003)

This yields: world map with varying color for cities with differing wsdi value

Note that wsdi is a continuous variable. Thus, ggplot uses a spectral palette. If you want to have dicrete colors (i.e. you group certain ranges of wsdi or factorise the values we simulated) you get a more colorful representation.

You can then move on to beautify the plot, e.g. add titles, change theme, etc.

Upvotes: 1

Related Questions