常用 7 大类型图形可视化——变化趋势图形

简介: 常用 7 大类型图形可视化——变化趋势图形

引言

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

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

本系列推文,小编将汇总可视化中常用 7 大类型图形,供读者参考。

常用 7 大类型图形可视化——组成成分图形

常用 7 大类型图形可视化——分布

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

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

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

每类制作成一篇推文,主要参考资料为:Top 50 ggplot2 Visualizations[1]。其他类似功能网站,资料包括:

  1. 庄闪闪的可视化笔记——常用图形[2]
  2. R Graph Gallery[3]
  3. 《R 语言教程》——ggplot 的各种图形[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()


6 变化趋势

6.1 时间序列图:基于时间序列对象(ts)

ggfortify 包中的 autoplot() 可以对时间序列直接绘图。在此基础上,添加其他 ggplot 相关函数。

library(ggplot2)
library(ggfortify)
theme_set(theme_classic())
# 绘图 
autoplot(AirPassengers) + 
  labs(title="AirPassengers") + 
  theme(plot.title = element_text(hjust=0.5))


时间序列图:基于时间序列对象(ts)

6.2 时间序列图:基于数据框

library(ggplot2)
theme_set(theme_classic())
# 使用默认的时间跨度
ggplot(economics, aes(x=date)) + 
  geom_line(aes(y=pce)) + 
  labs(title="Time Series Chart", 
       caption="Source: Economics")


economics 数据集预览:来自 ggplot2 包


时间序列图:基于数据框

如果想设置特定的时间间隔,则需要使用 scale_x_date() 函数。

library(ggplot2)
library(lubridate)
theme_set(theme_bw())
economics_m <- economics[1:24, ]
# 设定时间跨度为一个月
lbls <- paste0(month.abb[month(economics_m$date)], " ", lubridate::year(economics_m$date))
brks <- economics_m$date
# 绘图
ggplot(economics_m, aes(x=date)) + 
  geom_line(aes(y=pce)) + 
  scale_x_date(labels = lbls, 
               breaks = brks) +  # change to monthly ticks and labels
  theme(axis.text.x = element_text(angle = 90, vjust=0.5),  # rotate x axis text
        panel.grid.minor = element_blank())  # turn off minor grid


时间序列图:跨度为一个月

设置时间跨度为 1 年:

library(ggplot2)
library(lubridate)
theme_set(theme_bw())
economics_y <- economics[1:90, ] # 选择一年数据
# X轴文本的标签和 break 值
brks <- economics_y$date[seq(1, length(economics_y$date), 12)]
lbls <- lubridate::year(brks)
# 绘图
ggplot(economics_y, aes(x=date)) + 
  geom_line(aes(y=pce)) + 
  scale_x_date(labels = lbls, 
               breaks = brks) +  # change to monthly ticks and labels
  theme(axis.text.x = element_text(angle = 90, vjust=0.5),  # rotate x axis text
        panel.grid.minor = element_blank())


时间序列图:时间跨度为 1 年

6.3 多个时间序列

在本例中,基于长数据格式进行可视化。这意味着,所有列的列名和各自的值被存放在两个变量中(分别是 variablevalue)。

data(economics_long, package = "ggplot2")
head(economics_long)



在下面的代码中,在 geom_line() 函数中设置绘图对象为 value,颜色匹配对象为 variable。这样,只要调用一次 geom_line,就会绘制多条彩色线,每条线代表 variable 列中的每个唯一 valuescale_x_date() 将更改 X 轴断点和标签,scale_color_manual 将更改行颜色。

library(ggplot2)
library(lubridate)
theme_set(theme_bw())
df <- economics_long[economics_long$variable %in% c("psavert", "uempmed"), ]
df <- df[lubridate::year(df$date) %in% c(1967:1981), ]
# labels and breaks for X axis text
brks <- df$date[seq(1, length(df$date), 12)]
lbls <- lubridate::year(brks)
# 绘图
ggplot(df, aes(x=date)) + 
  geom_line(aes(y=value, col=variable)) + 
  labs(title="Time Series of Returns Percentage", 
       subtitle="Drawn from Long Data format", 
       caption="Source: Economics", 
       y="Returns %", 
       color=NULL) +  # title and caption
  scale_x_date(labels = lbls, breaks = brks) +  # change to monthly ticks and labels
  scale_color_manual(labels = c("psavert", "uempmed"), 
                     values = c("psavert"="#00ba38", "uempmed"="#f8766d")) +  # line color
  theme(axis.text.x = element_text(angle = 90, vjust=0.5, size = 8),  # rotate x axis text
        panel.grid.minor = element_blank())  # turn off minor grid


多个时间序列

如果从一个宽格式创建一个时间序列,则必须通过对每条线调用一次 geom_line() 。因此,默认情况下不会绘制图例,需要手动添加。

library(ggplot2)
library(lubridate)
theme_set(theme_bw())
df <- economics[, c("date", "psavert", "uempmed")]
df <- df[lubridate::year(df$date) %in% c(1967:1981), ]
# labels and breaks for X axis text
brks <- df$date[seq(1, length(df$date), 12)]
lbls <- lubridate::year(brks)
# plot
ggplot(df, aes(x=date)) + 
  geom_line(aes(y=psavert, col="psavert")) + 
  geom_line(aes(y=uempmed, col="uempmed")) + 
  labs(title="Time Series of Returns Percentage", 
       subtitle="Drawn From Wide Data format", 
       caption="Source: Economics", y="Returns %") +  # title and caption
  scale_x_date(labels = lbls, breaks = brks) +  # change to monthly ticks and labels
  scale_color_manual(name="", 
                     values = c("psavert"="#00ba38", "uempmed"="#f8766d")) +  # line color
  theme(panel.grid.minor = element_blank())  # turn off minor grid


多个时间序列

6.4 堆叠面积图

堆叠面积图与折线图类似,只是图下方的区域全部着色。应用场景有:

  • 想要描述数量或体积(而不是价格之类的变量)随时间的变化;
  • 有很多数据点。对于很少的数据点,可以考虑绘制柱状图。
  • 希望展示各个类别的贡献。
library(ggplot2)
library(lubridate)
theme_set(theme_bw())
df <- economics[, c("date", "psavert", "uempmed")]
df <- df[lubridate::year(df$date) %in% c(1967:1981), ]
# labels and breaks for X axis text
brks <- df$date[seq(1, length(df$date), 12)]
lbls <- lubridate::year(brks)
# plot
ggplot(df, aes(x=date)) + 
  geom_area(aes(y=psavert+uempmed, fill="psavert")) + 
  geom_area(aes(y=uempmed, fill="uempmed")) + 
  labs(title="Area Chart of Returns Percentage", 
       subtitle="From Wide Data format", 
       caption="Source: Economics", 
       y="Returns %") +  # title and caption
  scale_x_date(labels = lbls, breaks = brks) +  # change to monthly ticks and labels
  scale_fill_manual(name="", 
                    values = c("psavert"="#00ba38", "uempmed"="#f8766d")) +  # line color
  theme(panel.grid.minor = element_blank())  # turn off minor grid


堆叠面积图

6.5 日历热力图

当您想要在实际的日历上看到像股票价格这类指标的变化,特别是高点和低点时,日历热力图是一个很好的工具。它强调随着时间的推移视觉上的变化,而不是实际数值的变化。这可以通过使用 geom_tile() 来实现。

拓展:庄小编以前介绍过如何绘制日历图,可参见:calendR包—私人定制专属日历私人定制日历代码改进

library(ggplot2)
library(plyr)
library(scales)
library(zoo)
df <- read.csv("https://raw.githubusercontent.com/selva86/datasets/master/yahoo.csv")
df$date <- as.Date(df$date)  # 格式化日期
df <- df[df$year >= 2012, ]  # filter reqd years
# 创建月周
df$yearmonth <- as.yearmon(df$date)
df$yearmonthf <- factor(df$yearmonth)
df <- ddply(df,.(yearmonthf), transform, monthweek=1+week-min(week))  # compute week number of month
df <- df[, c("year", "yearmonthf", "monthf", "week", "monthweek", "weekdayf", "VIX.Close")]
head(df)



ggplot(df, aes(monthweek, weekdayf, fill = VIX.Close)) + 
  geom_tile(colour = "white") + 
  facet_grid(year~monthf) + 
  scale_fill_gradient(low="red", high="green") +
  labs(x="Week of Month",
       y="",
       title = "Time-Series Calendar Heatmap", 
       subtitle="Yahoo Closing Price", 
       fill="Close")



日历热力图

6.6 坡度图

坡度图可以可视化数值和类别排名之间的变化。这更适用于时间点很少的时间序列。下面给出使用 ggplot2 包绘制的案例,来源于:Top 50 ggplot2 Visualizations[5]。内部代码,这里不做过多解释,有能力的读者请自行研究!

此外,关于坡度图的绘制,也有些大佬已经集成 R 包了,例如:CGPfunctions[6] 包中的 newggslopegraph()slopegraph [7] 包中的 ggslopegraph() 绘制等。

library(dplyr)
theme_set(theme_classic())
source_df <- read.csv("https://raw.githubusercontent.com/jkeirstead/r-slopegraph/master/cancer_survival_rates.csv")
# 定义函数,来源: https://github.com/jkeirstead/r-slopegraph
tufte_sort <- function(df, x="year", y="value", group="group", method="tufte", min.space=0.05) {
    ## First rename the columns for consistency
    ids <- match(c(x, y, group), names(df))
    df <- df[,ids]
    names(df) <- c("x", "y", "group")
    ## Expand grid to ensure every combination has a defined value
    tmp <- expand.grid(x=unique(df$x), group=unique(df$group))
    tmp <- merge(df, tmp, all.y=TRUE)
    df <- mutate(tmp, y=ifelse(is.na(y), 0, y))
    ## Cast into a matrix shape and arrange by first column
    require(reshape2)
    tmp <- dcast(df, group ~ x, value.var="y")
    ord <- order(tmp[,2])
    tmp <- tmp[ord,]
    min.space <- min.space*diff(range(tmp[,-1]))
    yshift <- numeric(nrow(tmp))
    ## Start at "bottom" row
    ## Repeat for rest of the rows until you hit the top
    for (i in 2:nrow(tmp)) {
        ## Shift subsequent row up by equal space so gap between
        ## two entries is >= minimum
        mat <- as.matrix(tmp[(i-1):i, -1])
        d.min <- min(diff(mat))
        yshift[i] <- ifelse(d.min < min.space, min.space - d.min, 0)
    }
    tmp <- cbind(tmp, yshift=cumsum(yshift))
    scale <- 1
    tmp <- melt(tmp, id=c("group", "yshift"), variable.name="x", value.name="y")
    ## Store these gaps in a separate variable so that they can be scaled ypos = a*yshift + y
    tmp <- transform(tmp, ypos=y + scale*yshift)
    return(tmp)
}
plot_slopegraph <- function(df) {
    ylabs <- subset(df, x==head(x,1))$group
    yvals <- subset(df, x==head(x,1))$ypos
    fontSize <- 3
    gg <- ggplot(df,aes(x=x,y=ypos)) +
        geom_line(aes(group=group),colour="grey80") +
        geom_point(colour="white",size=8) +
        geom_text(aes(label=y), size=fontSize, family="American Typewriter") +
        scale_y_continuous(name="", breaks=yvals, labels=ylabs)
    return(gg)
}    
## 准备数据 
df <- tufte_sort(source_df, 
                 x="year", 
                 y="value", 
                 group="group", 
                 method="tufte", 
                 min.space=0.05)
df <- transform(df, 
                x=factor(x, levels=c(5,10,15,20), 
                            labels=c("5 years","10 years","15 years","20 years")), 
                y=round(y))
## 绘图
plot_slopegraph(df) + labs(title="Estimates of % survival rates") + 
                      theme(axis.title=element_blank(),
                            axis.ticks = element_blank(),
                            plot.title = element_text(hjust=0.5,
                                                      family = "American Typewriter",
                                                      face="bold"),
                            axis.text = element_text(family = "American Typewriter",
                                                     face="bold"))


坡度图

6.7 季节图

如果您正在处理 tsxts 类型的时间序列对象,您可以通过使用 forecast::ggseasonplot() 绘制的季节图来查看季节波动。下面是一个使用 AirPassengersnottem 数据集绘制的例子。

library(ggplot2)
library(forecast)
theme_set(theme_classic())
# 使用子集数据
nottem_small <- window(nottem, start=c(1920, 1), end=c(1925, 12))  # 使用较小时间窗的子集


nottem 数据集

ggseasonplot(nottem_small) + 
  labs(title="Seasonal plot: Air temperatures at Nottingham Castle")


nottem 数据集的季节图


AirPassengers 数据集

# 绘图
ggseasonplot(AirPassengers) + 
  labs(title="Seasonal plot: International Airline Passengers")


AirPassengers 数据集的季节图

参考资料

[1]

Top 50 ggplot2 Visualizations: http://r-statistics.co/Top50-Ggplot2-Visualizations-MasterList-R-Code.html

[2]

庄闪闪的可视化笔记——常用图形: https://liangliangzhuang.github.io/R-tutorial/main-diagram-types.html

[3]

R Graph Gallery: https://www.r-graph-gallery.com/ggplot2-package.html

[4]

R 语言教程——ggplot 的各种图形: https://www.math.pku.edu.cn/teachers/lidf/docs/Rbook/html/_Rbook/ggplotvis.html

[5]

Top 50 ggplot2 Visualizations: http://r-statistics.co/Top50-Ggplot2-Visualizations-MasterList-R-Code.html

[6]

CGPfunctions: https://cran.r-project.org/web/packages/CGPfunctions/vignettes/Using-newggslopegraph.html

[7]

slopegraph : https://rdrr.io/github/leeper/slopegraph/

目录
相关文章
|
2月前
|
数据可视化 Python
Matplotlab可视化学习笔记(二):如何绘制柱状图
使用Matplotlib库在Python中绘制柱状图的教程,包括基本的柱状图绘制和多条柱状图的绘制方法。
36 1
Matplotlab可视化学习笔记(二):如何绘制柱状图
|
2月前
|
数据可视化 Python
Matplotlab可视化学习笔记(一):如何绘制折线图
这篇博客介绍了如何使用Matplotlib库在Python中绘制折线图,包括常用颜色和线型、绘制多条折线图的方法、设置双y轴的技巧,以及如何保存和显示图表。
35 0
|
5月前
|
数据可视化 Linux 数据格式
`seaborn`是一个基于`matplotlib`的Python数据可视化库,它提供了更高级别的接口来绘制有吸引力的和信息丰富的统计图形。`seaborn`的设计目标是使默认图形具有吸引力,同时允许用户通过调整绘图参数来定制图形。
`seaborn`是一个基于`matplotlib`的Python数据可视化库,它提供了更高级别的接口来绘制有吸引力的和信息丰富的统计图形。`seaborn`的设计目标是使默认图形具有吸引力,同时允许用户通过调整绘图参数来定制图形。
|
7月前
|
数据可视化 定位技术
r语言空间可视化绘制道路交通安全事故地图
r语言空间可视化绘制道路交通安全事故地图
|
7月前
|
编解码 数据可视化
R语言动态可视化:绘制历史全球平均温度的累积动态折线图动画gif视频图
R语言动态可视化:绘制历史全球平均温度的累积动态折线图动画gif视频图
|
7月前
|
SQL 数据可视化 JavaScript
5款热门的图形报表推荐
5款热门的图形报表推荐
|
7月前
【SPSS】基础图形的绘制(条形图、折线图、饼图、箱图)详细操作过程(上)
【SPSS】基础图形的绘制(条形图、折线图、饼图、箱图)详细操作过程
811 0
|
7月前
【SPSS】基础图形的绘制(条形图、折线图、饼图、箱图)详细操作过程(下)
【SPSS】基础图形的绘制(条形图、折线图、饼图、箱图)详细操作过程
535 0
|
数据可视化 数据挖掘
常用 7 大类型图形可视化——组成成分图形
常用 7 大类型图形可视化——组成成分图形
129 0
|
数据可视化 数据挖掘
常用 7 大类型图形可视化——分布
常用 7 大类型图形可视化——分布
166 0