可视化系列汇总——排序关系

引言

在进行数据分析时,免不了对结果进行可视化。那么,什么样的图形才最适合自己的数据呢?一个有效的图形应具备以下特点:

  • 能正确传递信息,而不会产生歧义;
  • 样式简单,但是易于理解;
  • 添加的图形美学应辅助理解信息;
  • 图形上不应出现冗余无用的信息。

本系列推文,小编将汇总可视化中常用 7 大类型图形,供读者参考。每类制作成一篇推文,主要参考资料为:Top 50 ggplot2 Visualizations。其他类似功能网站,资料包括:

  1. 庄闪闪的可视化笔记——常用图形

  2. R Graph Gallery

  3. 《R 语言教程》——ggplot 的各种图形

系列目录

本文主要介绍第三部分:排序关系图形。

3 排序

3.1 有序条形图

有序条形图是按 Y 轴变量排序的条形图,X 轴变量必须转换为因子型(使用 factor() 函数),有序的处理:利用函数 order()

# 准备数据:按厂商分组计算平均城市里程。
cty_mpg <- aggregate(mpg$cty, by=list(mpg$manufacturer), FUN=mean)  # aggregate
colnames(cty_mpg) <- c("make", "mileage")  # change column names
cty_mpg <- cty_mpg[order(cty_mpg$mileage), ]  # sort
cty_mpg$make <- factor(cty_mpg$make, levels = cty_mpg$make)  # to retain the order in plot.
head(cty_mpg, 4)

ggplot(cty_mpg, aes(x=make, y=mileage)) + 
  geom_bar(stat="identity", width=.5, fill="tomato3") + 
  labs(title="Ordered Bar Chart", 
       subtitle="Make Vs Avg. Mileage", 
       caption="source: mpg") + 
  theme(axis.text.x = element_text(angle=65, vjust=0.6))

有序条形图

3.2 棒棒糖图

棒棒糖图传达的信息与柱状图相同。通过将粗条转变为细线,减少了杂乱,使图形看起来更美观。主要利用 geom_point()geom_segment() 函数。## 引言

在进行数据分析时,免不了对结果进行可视化。那么,什么样的图形才最适合自己的数据呢?一个有效的图形应具备以下特点:

  • 能正确传递信息,而不会产生歧义;
  • 样式简单,但是易于理解;
  • 添加的图形美学应辅助理解信息;
  • 图形上不应出现冗余无用的信息。

本系列推文,小编将汇总可视化中常用 7 大类型图形,供读者参考。每类制作成一篇推文,主要参考资料为:Top 50 ggplot2 Visualizations。其他类似功能网站,资料包括:

  1. 庄闪闪的可视化笔记——常用图形

  2. R Graph Gallery

  3. 《R 语言教程》——ggplot 的各种图形

系列目录

本文主要介绍第四部分:分布相关图形。前几部分可见:

  1. 常用 7 大类型图形可视化——相关关系图形

  2. 常用 7 大类型图形可视化——偏差关系图形

  3. 常用 7 大类型图形可视化——排序关系图形

这一部分也是小编最常使用的图形。写过的相关推文如:

  1. 复现 sci 顶刊中的 3D 密度函数图
  2. 与 ggplot2 包相关的 109 种拓展包
  3. 用ggpubr包制图
  4. 绘制混合密度函数图以及添加分位数线

加载数据集

使用 ggplot2 包中自带数据集作为示例数据集。

library(ggplot2)
library(plotrix)
data("midwest", package = "ggplot2") #加载数据集

midwest 数据集

全局主题设置

全局配色、主题设置。注意,本文使用离散色阶,如果需要使用连续色阶,则需要重写。

options(scipen=999)  # 关掉像 1e+48 这样的科学符号
# 颜色设置(灰色系列)
cbp1 <- c("#999999", "#E69F00", "#56B4E9", "#009E73",
          "#F0E442", "#0072B2", "#D55E00", "#CC79A7")

# 颜色设置(黑色系列)
cbp2 <- c("#000000", "#E69F00", "#56B4E9", "#009E73",
          "#F0E442", "#0072B2", "#D55E00", "#CC79A7")


ggplot <- function(...) ggplot2::ggplot(...) + 
  scale_color_manual(values = cbp1) +
  scale_fill_manual(values = cbp1) + # 注意: 使用连续色阶时需要重写
  theme_bw()

4 分布

4.1 直方图

4.4.1 连续变量的直方图

连续变量的直方图可以使用 geom_bar()geom_histogram() 来完成。当使用 geom_histogram() 时,可以使用 bins 参数来控制分箱的数量。也可以使用 binwidth 设置每个分箱覆盖的范围。 binwidth 的值与建立直方图的连续变量在同一个尺度上。

# 连续(数值)变量的直方图
g <- ggplot(mpg, aes(displ)) + scale_fill_brewer(palette = "Spectral")

g + geom_histogram(aes(fill=class), 
                   binwidth = .1, 
                   col="black", 
                   size=.1) +  # change binwidth
  labs(title="Histogram with Auto Binning", 
       subtitle="Engine Displacement across Vehicle Classes")

连续变量的直方图

g + geom_histogram(aes(fill=class), 
                   bins=5, 
                   col="black", 
                   size=.1) +   # change number of bins
  labs(title="Histogram with Fixed Bins", 
       subtitle="Engine Displacement across Vehicle Classes") 

连续变量的直方图

4.1.2 分类变量的直方图

分类变量的直方图实际上是根据每个类别的频率绘制的条形图。

library(ggplot2)
theme_set(theme_classic())

# Histogram on a Categorical variable
g <- ggplot(mpg, aes(manufacturer))
g + geom_bar(aes(fill=class), width = 0.5) + 
  theme(axis.text.x = element_text(angle=65, vjust=0.6)) + 
  labs(title="Histogram on Categorical Variable", 
       subtitle="Manufacturer across Vehicle Classes")

分类变量的直方图

4.2 密度图

g <- ggplot(mpg, aes(cty))
g + geom_density(aes(fill=factor(cyl)), alpha=0.8) + 
    labs(title="Density plot", 
         subtitle="City Mileage Grouped by Number of cylinders",
         caption="Source: mpg",
         x="City Mileage",
         fill="# Cylinders")

密度图

4.3 箱线图

箱形图是研究数据分布的一个有用工具。它还可以显示多个组内的分布,以及中值、范围和异常值。箱子内的黑线表示中位数。箱顶是 75% 分位数,箱底是 25% 分位数。线的端点(又称晶须)距离为1.5*IQR,其中 IQR (四分位差)是 25% 到 75% 分位数之间距离。须外的点通常被认为是极值点。设置 varwidth=T将调整盒子的宽度,使其与观察的数量成比例。

g <- ggplot(mpg, aes(class, cty))
g + geom_boxplot(varwidth=T, fill="plum") + 
    labs(title="Box plot", 
         subtitle="City Mileage grouped by Class of vehicle",
         caption="Source: mpg",
         x="Class of Vehicle",
         y="City Mileage")
 

箱线图 1

g <- ggplot(mpg, aes(class, cty))
g + geom_boxplot(aes(fill=factor(cyl))) + 
  theme(axis.text.x = element_text(angle=65, vjust=0.6)) + 
  labs(title="Box plot", 
       subtitle="City Mileage grouped by Class of vehicle",
       caption="Source: mpg",
       x="Class of Vehicle",
       y="City Mileage")

箱线图 2

这个部分小编在科技论文中常常会使用,具体推文可见:

4.4 点图+箱线图

在箱线图的基础上,添加点图可以提供更清晰的信息。这些点交错排列,每个点代表一次观测。

g <- ggplot(mpg, aes(manufacturer, cty))
g + geom_boxplot() + 
  geom_dotplot(binaxis='y', 
               stackdir='center', 
               dotsize = .5, 
               fill="red") +
  theme(axis.text.x = element_text(angle=65, vjust=0.6)) + 
  labs(title="Box plot + Dot plot", 
       subtitle="City Mileage vs Class: Each dot represents 1 row in source data",
       caption="Source: mpg",
       x="Class of Vehicle",
       y="City Mileage")
 

4.5 塔夫特箱线图

这是一个简化版的箱线图。


library(ggthemes)
library(ggplot2)
theme_set(theme_tufte())  # from ggthemes

# plot
g <- ggplot(mpg, aes(manufacturer, cty))
g + geom_tufteboxplot() + 
      theme(axis.text.x = element_text(angle=65, vjust=0.6)) + 
      labs(title="Tufte Styled Boxplot", 
           subtitle="City Mileage grouped by Class of vehicle",
           caption="Source: mpg",
           x="Class of Vehicle",
           y="City Mileage")

塔夫特箱线图

4.6 小提琴图

小提琴图类似于箱线图,但显示了组内的密度。

g <- ggplot(mpg, aes(class, cty))
g + geom_violin() + 
  labs(title="Violin plot", 
       subtitle="City Mileage vs Class of vehicle",
       caption="Source: mpg",
       x="Class of Vehicle",
       y="City Mileage")

绘制箱线图及小提琴图也可以参考ggstanceggpubr,或者去网站搜索相关 ggplot 拓展的 R 包。我写过的相关类型可见推文:xxx。

4.7 金字塔图

金字塔图提供了一种独特的方式来可视化每个类别包含的样本比例。下面的金字塔是一个很好的例子,说明了在一个营销活动中每个阶段的用户留存率。

library(ggplot2)
library(ggthemes)
options(scipen = 999)  # turns of scientific notations like 1e+40

# Read data
email_campaign_funnel <- read.csv("https://raw.githubusercontent.com/selva86/datasets/master/email_campaign_funnel.csv")

# X Axis Breaks and Labels 
brks <- seq(-15000000, 15000000, 5000000)
lbls = paste0(as.character(c(seq(15, 0, -5), seq(5, 15, 5))), "m")

# Plot
ggplot(email_campaign_funnel, aes(x = Stage, y = Users, fill = Gender)) +   # Fill column
                              geom_bar(stat = "identity", width = .6) +   # draw the bars
                              scale_y_continuous(breaks = brks,   # Breaks
                                                 labels = lbls) + # Labels
                              coord_flip() +  # Flip axes
                              labs(title="Email Campaign Funnel") +
                              theme_tufte() +  # Tufte theme from ggfortify
                              theme(plot.title = element_text(hjust = .5), 
                                    axis.ticks = element_blank()) +   # Centre plot title
                              scale_fill_brewer(palette = "Dark2")  # Color palette

金字塔图

这个图经常有人在群里问,很多是横向的(只需要去除 coord_flip()),如果需要添加误差限,可以使用 geom_errorbar()

ggplot(cty_mpg, aes(x=make, y=mileage)) + 
  geom_point(size=3) + 
  geom_segment(aes(x=make, 
                   xend=make, 
                   y=0, 
                   yend=mileage)) + 
  labs(title="Lollipop Chart", 
       subtitle="Make Vs Avg. Mileage", 
       caption="source: mpg") + 
  theme(axis.text.x = element_text(angle=65, vjust=0.6))

3.3 点图

点图非常类似于棒棒糖图,但没有线条,并且各标签都在水平位置上。它更强调项目的顺序与实际值有关。

注意代码中的 geom_segment() 内的 x 和 xend 的设置。以及最后使用了 coord_flip() 反转坐标轴。

ggplot(cty_mpg, aes(x=make, y=mileage)) + 
  geom_point(col="tomato2", size=3) +   # Draw points
  geom_segment(aes(x=make, 
                   xend=make, 
                   y=min(mileage), 
                   yend=max(mileage)), 
               linetype="dashed", 
               size=0.1) +   # Draw dashed lines
  labs(title="Dot Plot", 
       subtitle="Make Vs Avg. Mileage", 
       caption="source: mpg") +  
  coord_flip()

点图

3.4 坡度图

坡度图是比较两点之间差异的绝佳方法。目前,还没有内置函数来构建这个图形。下面的代码可以作为一个示例框架,告诉您如何绘制这个图形。

先展示下数据:

library(scales)
# 数据准备
df <- read.csv("https://raw.githubusercontent.com/selva86/datasets/master/gdppercap.csv")
colnames(df) <- c("continent", "1952", "1957")
left_label <- paste(df$continent, round(df$'1952'),sep=", ")
right_label <- paste(df$continent, round(df$'1957'),sep=", ")
df$class <- ifelse((df$'1957' - df$'1952') < 0, "red", "green")
head(df)

library(ggplot2)
p <- ggplot(df) + geom_segment(aes(x=1, xend=2, y=`1952`, yend=`1957`, col=class), size=.75, show.legend=F) + 
                  geom_vline(xintercept=1, linetype="dashed", size=.1) + 
                  geom_vline(xintercept=2, linetype="dashed", size=.1) +
                  scale_color_manual(labels = c("Up", "Down"), 
                                     values = c("green"="#00ba38", "red"="#f8766d")) +  # color of lines
                  labs(x="", y="Mean GdpPerCap") +  # Axis labels
                  xlim(.5, 2.5) + ylim(0,(1.1*(max(df$`1952`, df$`1957`))))  # X and Y axis limits

# Add texts
p <- p + geom_text(label=left_label, y=df$`1952`, x=rep(1, NROW(df)), hjust=1.1, size=3.5)
p <- p + geom_text(label=right_label, y=df$`1957`, x=rep(2, NROW(df)), hjust=-0.1, size=3.5)
p <- p + geom_text(label="Time 1", x=1, y=1.1*(max(df$`1952`, df$`1957`)), hjust=1.2, size=5)  # title
p <- p + geom_text(label="Time 2", x=2, y=1.1*(max(df$`1952`, df$`1957`)), hjust=-0.1, size=5)  # title


#设置主题
p + theme(panel.background = element_blank(),
           panel.grid = element_blank(),
           axis.ticks = element_blank(),
           axis.text.x = element_blank(),
           panel.border = element_blank(),
           plot.margin = unit(c(1,2,1,2), "cm"))

图形是通过线段,竖线构成,之后添加文字。这是纯 ggplot 码出来的图形。当然现在也有现成的包可以完成。例如:CGPfunctions。它可以得到的结果实例如下:

来源:https://ibecav.github.io/CGPfunctions/

来源:https://ibecav.github.io/CGPfunctions/

3.5 哑铃图

哑铃图作用:

  1. 比较两个时间点之间的相对位置(比如增长和下降);
  2. 比较两类之间的距离。

为了得到哑铃的正确顺序,Y 变量应该是一个因子,因子变量的水平应该与它在图中出现的顺序相同。

数据如下:

health <- read.csv("https://raw.githubusercontent.com/selva86/datasets/master/health.csv")
health$Area <- factor(health$Area, levels=as.character(health$Area))  # for right ordering of the dumbells
# health$Area <- factor(health$Area)
head(health)

直接使用 geom_dumbbel() 绘制哑铃图。之后就是一些细节的调整。

gg <- ggplot(health, aes(x=pct_2013, xend=pct_2014, y=Area, group=Area)) + 
        geom_dumbbell(color="#a3c4dc", 
                      size=0.75, 
                      point.colour.l="#0e668b") + 
        scale_x_continuous(label=percent) + 
        labs(x=NULL, 
             y=NULL, 
             title="Dumbbell Chart", 
             subtitle="Pct Change: 2013 vs 2014", 
             caption="Source: https://github.com/hrbrmstr/ggalt") +
        theme(plot.title = element_text(hjust=0.5, face="bold"),
              plot.background=element_rect(fill="#f7f7f7"),
              panel.background=element_rect(fill="#f7f7f7"),
              panel.grid.minor=element_blank(),
              panel.grid.major.y=element_blank(),
              panel.grid.major.x=element_line(),
              axis.ticks=element_blank(),
              legend.position="top",
              panel.border=element_blank())
plot(gg)

拓展的哑铃图可以参考这个链接,得到的示意图如下。这里代码就不贴出来了,需要的读者自行去网站下载。主要是在基础版本上,加入阴影(geom_rect())、线段(geom_segment),竖线(geom_vline)。

来源:https://r-graph-gallery.com

来源:https://r-graph-gallery.com

小编有话说

这个系列的推文,只是给出了最简约的图形,并没有在美观上进行设计。主要让读者了解,绘制什么图形,应该使用什么函数/包。具体的美观设计,暂时不做设计,可以在主题、配色上做文章。类似的推文小编整理了些,可供参考:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值