简介
通过分面,您可以创建多面板图,并控制一个面板的坐标刻度如何与另一个面板的刻度关联。
分面的简单用法
如果您对 ggplot2 稍有了解,就会知道调用 ggplot() 函数的基本结构。关于 ggplot2 的入门,您可以查看我们的 ggplot2 课程 。调用 ggplot 时,您需要提供一个数据源,通常是一个数据框 ,然后让 ggplot 将数据源中的不同变量映射到不同的美学属性上,例如 x 或 y 轴的位置,或者点或柱的颜色。借助分面,您还能以另一种方式映射变量。为演示这一点,您将使用下列数据集,其中包含若干国家的经济指标。大多数变量都是关于各国 GDP(国内生产总值)的不同变体。
print( econdata) 技术支持
技术支持
包含以下变量:
Country:不言自明!
GDP_nom:以美元计的名义国内生产总值
GDP_PPP:经购买力平价调整的国内生产总值
GDP_nom_per_capita:以美元计的人均名义国内生产总值
GDP_PPP_per_capita:经购买力平价调整的人均国内生产总值
GNI_per_capita:各国的人均国民总收入。
Region:该国家所在的世界区域。
首先,让我们绘制各国名义 GDP 的简单柱状图。
ggplot( econdata, aes( x= Country, y= GDP_nom) ) +
geom_bar( stat= 'identity' , fill= "forest green" ) +
ylab( "GDP (nominal)" ) 技术支持
您也可以绘制另一个变量,即经 PPP 调整的 GDP。
ggplot ( econdata, aes ( x= Country, y= GDP_PPP ) ) +
geom_bar ( stat= 'identity' , fill= "forest green" ) +
ylab ( "GDP (PPP)" )
技术支持
这会生成第二个独立图,与上一个类似,但使用了不同变量。假设您想将名义 GDP 和 PPP GDP 放在一起绘制。您将使用分面来实现。首先,需要将数据从“宽表”格式(每个变量一列)改为“长表”格式,即用一列存放度量值,另一列作为键变量,指示每一行所使用的度量。
econdatalong < - gather ( econdata, key= "measure" , value= "value" , c ( "GDP_nom" , "GDP_PPP" ) )
技术支持
一旦数据转成这种格式,就可以利用键变量来绘制分面图。我们来构建一个简单的图,同时展示名义 GDP(来自第一个图)和 GDP(PPP)(来自第二个图)。为此,您只需在代码中添加 +facet_wrap(),并指定使用 ~measure(我们的键变量)进行分面。
ggplot ( econdatalong, aes ( x= Country, y= value) ) +
geom_bar ( stat= 'identity' , fill= "forest green" ) +
facet_wrap ( ~ measure)
技术支持
这确实可行,但您会注意到国家名称被挤得很紧。让我们调整面板布局。
自定义布局与重新排序
facet_wrap() 会自动决定使用多少列。您也可以通过 ncol= 直接指定,如下所示:
ggplot ( econdatalong, aes ( x= Country, y= value) ) +
geom_bar ( stat= 'identity' , fill= "forest green" ) +
facet_wrap ( ~ measure, ncol= 1 )
技术支持
您可能注意到上图 x 轴上的国家按字母顺序排列。如果想更改这一点,最简单的方法是设置 Country 因子的水平。让我们按照名义 GDP 总量对国家重新排序。
econdata$Country < - factor ( econdata$Country, levels= econdata$Country[ order ( econdata$GDP_nom) ] )
econdatalong < - gather ( econdata, key= "measure" , value= "value" , c ( "GDP_nom" , "GDP_PPP" ) )
ggplot ( econdatalong, aes ( x= Country, y= value) ) +
geom_bar ( stat= 'identity' , fill= "forest green" ) +
facet_wrap ( ~ measure, ncol= 1 )
技术支持
您还可以进行一些额外的自定义,比如通过 strip.position 参数将分面标签移动到左侧。
ggplot ( econdatalong, aes ( x= Country, y= value) ) +
geom_bar ( stat= 'identity' , fill= "forest green" ) +
facet_wrap ( ~ measure, ncol= 1 , strip. position = "left" )
技术支持
为分面添加标签
您可能已经注意到,分面的简短标题来自因子 measure 的水平。让我们整理一下,为分面提供更友好的标签。为此,您将编写一个简单的标注函数 variable_labeller,当输入 variable_names 的某个值时,它会返回相应名称。然后将该函数传递给 facet_wrap 的 labeller 参数。
variable_names < - list (
"GDP_nom" = "GDP (nominal)" ,
"GDP_PPP" = "GDP (purchasing power parity)"
)
variable_labeller < - function ( variable, value ) {
return ( variable_names[ value] )
}
ggplot ( econdatalong, aes ( x= Country, y= value) ) +
geom_bar ( stat= 'identity' , fill= "forest green" ) +
facet_wrap ( ~ measure, ncol= 1 , labeller= variable_labeller)
技术支持
调整刻度与空间
让我们构建一个更大的分面图,使用所有经济度量。
econdatalong < - gather ( econdata, key= "measure" , value= "value" , c ( "GDP_nom" , "GDP_PPP" , "GDP_nom_per_capita" , "GDP_PPP_per_capita" , "GNI_per_capita" ) )
variable_names < - list (
"GDP_nom" = "GDP (nominal)" ,
"GDP_PPP" = "GDP (purchasing power parity)" ,
"GDP_nom_per_capita" = "GDP (nominal) per capita" ,
"GDP_PPP_per_capita" = "GDP (purchasing power parity) per capita" ,
"GNI_per_capita" = "GNI per capita"
)
variable_labeller < - function ( variable, value ) {
return ( variable_names[ value] )
}
ggplot ( econdatalong, aes ( x= Country, y= value) ) +
geom_bar ( stat= 'identity' , fill= "forest green" ) +
facet_wrap ( ~ measure, ncol= 1 , labeller= variable_labeller) +
scale_y_continuous ( breaks = pretty ( econdatalong$value, n = 10 ) )
技术支持
这完全不行!您看不到其中三个面板的取值。为什么?让我们看看原始数据找原因。
summary( econdata) 技术支持
技术支持
查看每一列会发现,各列的取值跨越了几个数量级。默认情况下,分面会对 X 轴和 Y 轴使用相同的范围和刻度。若要更改,您可以在分面代码中添加 scales="free_y",使每个分面使用各自独立的刻度。
ggplot( econdatalong, aes( x= Country, y= value) ) +
geom_bar( stat= 'identity' , fill= "forest green" ) +
facet_wrap( ~ measure, scales= "free_y" , ncol= 1 , labeller= variable_labeller) 技术支持
这就好多了。现在每个分面都有各自独立的 y 轴。
使用分面创建细分
您可能注意到,数据集中还包含变量 Region,表示该国家所在的地区。您可以用它为柱形按地区着色,如下所示:
ggplot( econdatalong, aes( x= Country, y= value, fill= Region) ) +
geom_bar( stat= 'identity' ) +
facet_wrap( ~ measure, scales= "free_y" , ncol= 1 , labeller= variable_labeller) 技术支持
不过这有点乱。如果能把不同地区分别放到各自的子面板就好了?使用分面就能做到!这里我们将使用 facet_grid 而非 facet_wrap,这样更容易将分面映射到两个变量上:Region 和 measure,并把这两个变量分布到图表网格的行与列上。注意我们还设置了 scales="free" 和 space="free",允许不同面板占用不同的空间。您还需要创建一个新的标注函数,为行与列同时生成名称。
variable_names <- list(
"GDP_nom" = "GDP \n(nominal)" ,
"GDP_PPP" = "GDP \n(PPP)" ,
"GDP_nom_per_capita" = "GDP (nominal)\n per capita" ,
"GDP_PPP_per_capita" = "GDP (PPP)\n per capita" ,
"GNI_per_capita" = "GNI \nper capita"
)
region_names <- levels( econdata$ Region)
variable_labeller2 <- function ( variable, value) {
if ( variable== 'measure' ) {
return( variable_names[ value] )
} else {
return( region_names)
}
}
ggplot( econdatalong, aes( x= Country, y= value, fill= Region) ) +
geom_bar( stat= 'identity' ) +
facet_grid( measure~ Region, scales= "free" , space= "free_x" , labeller= variable_labeller2) 技术支持
现在清晰多了!每个地区都有自己的列,每个指标都有自己的一行柱形图。
本教程到此结束。希望您在学习分面时有所收获。
如果您想进一步了解分面,请学习 DataCamp 的 使用 Trelliscope 可视化大数据 课程。
查看我们的 Tidyverse 入门:教程 。
简介
通过分面,您可以创建多面板图,并控制一个面板的坐标刻度如何与另一个面板的刻度关联。
分面的简单用法
如果您对 ggplot2 稍有了解,就会知道调用
ggplot()函数的基本结构。关于 ggplot2 的入门,您可以查看我们的 ggplot2 课程。调用ggplot时,您需要提供一个数据源,通常是一个数据框,然后让 ggplot 将数据源中的不同变量映射到不同的美学属性上,例如 x 或 y 轴的位置,或者点或柱的颜色。借助分面,您还能以另一种方式映射变量。为演示这一点,您将使用下列数据集,其中包含若干国家的经济指标。大多数变量都是关于各国 GDP(国内生产总值)的不同变体。包含以下变量:
Country:不言自明!
GDP_nom:以美元计的名义国内生产总值
GDP_PPP:经购买力平价调整的国内生产总值
GDP_nom_per_capita:以美元计的人均名义国内生产总值
GDP_PPP_per_capita:经购买力平价调整的人均国内生产总值
GNI_per_capita:各国的人均国民总收入。
Region:该国家所在的世界区域。
首先,让我们绘制各国名义 GDP 的简单柱状图。
您也可以绘制另一个变量,即经 PPP 调整的 GDP。
这会生成第二个独立图,与上一个类似,但使用了不同变量。假设您想将名义 GDP 和 PPP GDP 放在一起绘制。您将使用分面来实现。首先,需要将数据从“宽表”格式(每个变量一列)改为“长表”格式,即用一列存放度量值,另一列作为键变量,指示每一行所使用的度量。
一旦数据转成这种格式,就可以利用键变量来绘制分面图。我们来构建一个简单的图,同时展示名义 GDP(来自第一个图)和 GDP(PPP)(来自第二个图)。为此,您只需在代码中添加
+facet_wrap(),并指定使用~measure(我们的键变量)进行分面。这确实可行,但您会注意到国家名称被挤得很紧。让我们调整面板布局。
自定义布局与重新排序
facet_wrap()会自动决定使用多少列。您也可以通过ncol=直接指定,如下所示:您可能注意到上图 x 轴上的国家按字母顺序排列。如果想更改这一点,最简单的方法是设置
Country因子的水平。让我们按照名义 GDP 总量对国家重新排序。您还可以进行一些额外的自定义,比如通过
strip.position参数将分面标签移动到左侧。为分面添加标签
您可能已经注意到,分面的简短标题来自因子
measure的水平。让我们整理一下,为分面提供更友好的标签。为此,您将编写一个简单的标注函数variable_labeller,当输入variable_names的某个值时,它会返回相应名称。然后将该函数传递给facet_wrap的labeller参数。调整刻度与空间
让我们构建一个更大的分面图,使用所有经济度量。
这完全不行!您看不到其中三个面板的取值。为什么?让我们看看原始数据找原因。
查看每一列会发现,各列的取值跨越了几个数量级。默认情况下,分面会对 X 轴和 Y 轴使用相同的范围和刻度。若要更改,您可以在分面代码中添加
scales="free_y",使每个分面使用各自独立的刻度。这就好多了。现在每个分面都有各自独立的 y 轴。
使用分面创建细分
您可能注意到,数据集中还包含变量
Region,表示该国家所在的地区。您可以用它为柱形按地区着色,如下所示:不过这有点乱。如果能把不同地区分别放到各自的子面板就好了?使用分面就能做到!这里我们将使用
facet_grid而非facet_wrap,这样更容易将分面映射到两个变量上:Region和measure,并把这两个变量分布到图表网格的行与列上。注意我们还设置了scales="free"和space="free",允许不同面板占用不同的空间。您还需要创建一个新的标注函数,为行与列同时生成名称。现在清晰多了!每个地区都有自己的列,每个指标都有自己的一行柱形图。
本教程到此结束。希望您在学习分面时有所收获。
如果您想进一步了解分面,请学习 DataCamp 的 使用 Trelliscope 可视化大数据 课程。
查看我们的 Tidyverse 入门:教程。