简体   繁体   English

如何使用ggplot2编辑图例的位置

[英]How can I edit the place of the legends with ggplot2

I am having trouble in separating the legends in a ggplot2 graph with multiple layers. 我在用多层分割ggplot2图中的图例时遇到麻烦。 What my plot does is to fill different municipalities according to the number of textile companies present there and I also plot the plant localization with geom_point . 我的情节是根据那里的纺织公司的数量来填充不同的城市,我还用geom_point绘制工厂的geom_point My guess is to use aes.override() somehow, but I haven't been able to do this still. 我的猜测是以某种方式使用aes.override() ,但我仍然无法做到这一点。 The solutions that I have read do not deal with a different variable for the plots detailed in the aes() of geom_point() . 我阅读的解决方案没有为geom_point()aes()中详细介绍的图处理不同的变量。

If you want to test the code below, you could download the shapefile for the brazilian municipalities here , use readOGR and fortify , then choose to fill the municipalities with your preference with fill and set arbitrarily random points within Brazil for geom_point() creating a different variable, such as lat_plant and long_plant below. 如果您想在下面测试代码,你可以下载shape文件为巴西直辖市这里 ,使用readOGRfortify ,然后选择与您的喜好来填补直辖市fill并在巴西任意设定随机点geom_point()创建一个不同的变量,例如下面的lat_plantlong_plant The region column below details brazilian regions -- in this case, the "1" details the northern region of Brazil. 下面的region列详细说明了巴西地区-在这种情况下,“ 1”详细说明了巴西北部地区。

The Code 编码

#setting the ggplot    
library(ggplot2)

gg2 < -ggplot(data = out[out$region =="1",], 
              aes(x = long, y = lat, group = group, fill = as.factor(companies))) + 
       geom_polygon() + 
       ggtitle("title") + 
       scale_fill_discrete(name = "Number of Textile Companies") +
       theme(plot.title = element_text(size = 30, face = "bold")) +
       theme(legend.text = element_text(size = 12),
             legend.title = element_text(colour = "blue", size = 16, face = "bold")) 

#graph output

gg2 + 
geom_point(data = out[out$region =="1",], aes(x = long_plant, y = lat_plant), color = "red") 

What I am getting as legend is this: 作为传说,我得到的是:

在此处输入图片说明

And I would like to separate it, detailing that the dots as localizations and the colors as the filling for the number of textile companies in the region. 我想将其分开,详细说明以点表示的本地化和以颜色表示的该地区纺织公司的数量。

I leave another option for you. 我给你别的选择。 hmgeiger treated the number of textile companies as factor. hmgeiger将纺织公司的数量作为因素。 But, I rather treated the variable as a continuous variable. 但是,我宁愿将变量视为连续变量。 Since there is NO reproducible data, I created a sample data by myself. 由于没有可复制的数据,因此我自己创建了一个样本数据。 Here, I created random samples uing longitude and latitude of Brazil, and made sure that some data points stay in Brazil. 在这里,我使用巴西的经度和纬度创建了随机样本,并确保某些数据点保留在巴西。 whatever2 contains data points staying in Brazil. whatever2包含停留在巴西的数据点。 I did a bit of trick here as well. 我在这里也做了一些技巧。 I added a new column called Factory location . 我添加了一个名为Factory location的新列。 This is the dummy variable for adding color to data points in the final graphic. 这是用于向最终图形中的数据点添加颜色的虚拟变量。 hmgeiger created Dummy.var that contains characters for you. hmgeiger创建了Dummy.var ,其中包含适合您的字符。 I rather left "" in this column since you may not want to see any text in legend. 我宁愿在此列中保留"" ,因为您可能不想在图例中看到任何文本。

For your legend issue, as Antonio mentioned and hmgeiger did, you need to add color in aes() in geom_point() . 对于您的传奇问题,就像Antonio提到的和hmgeiger所做的那样,您需要在geom_point() aes()中添加颜色。 This solves it. 这解决了。 I did a bit more thing for you. 我为您做了更多的事情。 If you do not know how many factories exist in each municipal, you need to count the number of factories. 如果您不知道每个城市有多少家工厂,则需要计算工厂数量。 I did the job using poly.count() in the GISTools package and created another data frame that contains the numbers of factories in each municipal. 我做了使用作业poly.count()GISTools包,创建了一个包含每个城市的工厂的数量另一个数据帧。

When I drew the map, I had three layers. 绘制地图时,我有三层。 One is for the polygons and another for filling the polygons with colors. 一种用于多边形,另一种用于用颜色填充多边形。 They are done with geom_cartogram() from the ggalt package. 它们通过ggalt包中的geom_cartogram()完成。 The key thing is that you need to have a common key column for map_id . 关键是您需要为map_id拥有一个公共键列。 id in the first geom_cartogram() and ind in the second geom_cartogram() are identical information. 第一个geom_cartogram()中的id和第二个geom_cartogram()中的ind是相同的信息。 In geom_point() you need color in aes() . geom_point() ,需要在aes() color The legend has a continuous bar for the number of factories and a single dot for factory location. 图例有一个连续的条形表示工厂数量,一个点表示工厂位置。 No text exists next to it. 旁边没有文字。 So this makes the legend tidy, I think. 我想,这使传说变得整洁。

library(raster)
library(tidyverse)
library(GISTools)
library(RColorBrewer)
library(ggalt)
library(ggthemes)

# Get polygon data for Brazil
brazil <- getData("GADM", country = "brazil", level = 1)

mymap <- fortify(brazil)

# Create dummy data staying in the polygons
# For more information: https://stackoverflow.com/questions/47696382/removing-data-outside-country-map-boundary-in-r/47699405#47699405
set.seed(123)
mydata <- data.frame(long = runif(200, min = quantile(mymap$long)[1], max = quantile(mymap$long)[4]),
                     lat = runif(200, min = quantile(mymap$lat)[1], max = quantile(mymap$lat)[4]),
                     factory = paste("factory ", 1:200, sep = ""),
                     stringsAsFactors = FALSE)

spdf <- SpatialPointsDataFrame(coords = mydata[, c("long", "lat")], data = mydata,
                               proj4string = CRS("+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"))


whatever <- spdf[!is.na(over(spdf, as(brazil, "SpatialPolygons"))), ]

whatever2 <- as.data.frame(whatever) %>%
             mutate(`Factory location` = "")


# Now I check how many data points (factories) exist in each polygon
# and create a data frame
factory.num <- poly.counts(pts = whatever, polys = brazil)
factory.num <- stack(factory.num)


ggplot() +
geom_cartogram(data = mymap, aes(x = long, y = lat, map_id = id),
               map = mymap) +
geom_cartogram(data = factory.num, aes(fill = values, map_id = ind),
               map = mymap) +
geom_point(data = whatever2, aes(x = long, y = lat, color = `Factory location`)) +
scale_fill_gradientn(name = "Number of factories", colours = brewer.pal(5, "Greens")) +
coord_map() +
theme_map()

在此处输入图片说明

FYI, the link you posted to download the shape file is quite slow, at least to download to a US computer. 仅供参考,您发布的下载形状文件的链接非常慢,至少要下载到美国计算机上。

This link has downloads that work a lot better, and also shows how to read in shape data: https://dioferrari.wordpress.com/2014/11/27/plotting-maps-using-r-example-with-brazilian-municipal-level-data/ 该链接的下载效果更好,并且还展示了如何读取形状数据: https : //dioferrari.wordpress.com/2014/11/27/plotting-maps-using-r-example-with-brazilian-市政级数据/

I made an example using the regions rather than municipalities data to keep it simple. 为了简化起见,我使用区域而不是市政数据作为示例。

Data I used available for download here: https://drive.google.com/file/d/0B64xLcn8DZfwakNMbHFLQWo4YzA/view?usp=sharing 我用于下载的数据可在此处下载: https : //drive.google.com/file/d/0B64xLcn8DZfwakNMbHFLQWo4YzA/view?usp=sharing

#Load libraries.

library(rgeos)
library(rgdal)
library(ggplot2)

#Read in and format map data.

regions_OGR <- readOGR(dsn="/Users/hmgeiger/Downloads/regioes_2010",
layer = "regioes_2010")
map_regions <- spTransform(regions_OGR,CRS("+proj=longlat +datum=WGS84"))
map_regions_fortified <- fortify(map_regions)

#We make there be 0, 1, or 3 textile companies.
#map_regions_fortified is in  order by ID (region).
#So, we add a column with the number of textile companies 
#repeated the right number of times for how many of each region there is.

num_rows_per_region <- data.frame(table(map_regions_fortified$id))

map_regions_fortified <- data.frame(map_regions_fortified,
Num.factories = factor(rep(c(1,0,1,3,1),times=num_rows_per_region$Freq)))

#First, plot without any location dots.

ggplot()+geom_polygon(data=map_regions_fortified,
aes(x = long,y = lat, group=group, fill=Num.factories),colour="black")

Now, let's add the factory locations. 现在,让我们添加工厂位置。

#Set latitude and longitude based on the number of factories per region.

factory_locations <- data.frame(long = c(-65,-55,-51,-44,-42,-38),
lat = c(-5,-15,-27,-7,-12,-8))

#Add a dummy variable, which then allows the colour of the dots 
#to be a part of the legend.

factory_locations <- data.frame(factory_locations,
Dummy.var = rep("One dot = one factory location",times=nrow(factory_locations)))

#Replot adding factory location dots.
#We will use black dots here since will be easier to see.

ggplot()+geom_polygon(data=map_regions_fortified,
aes(x = long,y = lat, group=group, fill=Num.factories),colour="black")       
+ geom_point(data = factory_locations,aes(x = long,y = lat,colour = Dummy.var)) 
+ scale_colour_manual(values="black") + labs(colour="")

#Bonus: Let's change the color vector to something more color-blind friendly.

mycol <- c("#E69F00", "#56B4E9", "#009E73", "#F0E442", 
"#0072B2", "#D55E00", "#CC79A7","#490092")

ggplot()+geom_polygon(data=map_regions_fortified,
aes(x = long,y = lat, group=group, fill=Num.factories),colour="black")       
+ geom_point(data = factory_locations,aes(x = long,y = lat,colour = Dummy.var)) 
+ scale_colour_manual(values="black") + labs(colour="") 
+ scale_fill_manual(values=mycol)

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM