直方图和散点图是可视化数据和变量关系的很好的方法,但最近我一直在思考我错过了哪些可视化技术。你认为最不常用的图表类型是什么?
回答应该:
- 在实践中不是非常常用。
- 不需要太多的背景讨论就可以理解。
- 适用于许多常见情况。
- 包括可重复运行的代码示例(最好用R),可以附带链接图片。
回答应该:
我非常赞同其他帖子的观点:Tufte的书籍非常出色,值得一读。
首先,我想向您介绍今年早些时候“看数据”从ggplot2和ggobi的非常好的教程。除此之外,我只想强调R中的一个可视化和两个图形包(它们没有基础图形、格栅或ggplot那么广泛使用):
热度图
我真的很喜欢可以处理多变量数据的可视化,尤其是时间序列数据。热度图对此非常有用。David Smith在Revolutions博客上推荐了一个非常棒的热度图。这是Hadley提供的ggplot代码:
stock <- "MSFT"
start.date <- "2006-01-12"
end.date <- Sys.Date()
quote <- paste("http://ichart.finance.yahoo.com/table.csv?s=",
stock, "&a=", substr(start.date,6,7),
"&b=", substr(start.date, 9, 10),
"&c=", substr(start.date, 1,4),
"&d=", substr(end.date,6,7),
"&e=", substr(end.date, 9, 10),
"&f=", substr(end.date, 1,4),
"&g=d&ignore=.csv", sep="")
stock.data <- read.csv(quote, as.is=TRUE)
stock.data <- transform(stock.data,
week = as.POSIXlt(Date)$yday %/% 7 + 1,
wday = as.POSIXlt(Date)$wday,
year = as.POSIXlt(Date)$year + 1900)
library(ggplot2)
ggplot(stock.data, aes(week, wday, fill = Adj.Close)) +
geom_tile(colour = "white") +
scale_fill_gradientn(colours = c("#D61818","#FFAE63","#FFFFBD","#B5E384")) +
facet_wrap(~ year, ncol = 1)
最终看起来会有点像这样:
RGL: 交互式3D图形
另一个值得学习的软件包是RGL,它可以轻松地创建交互式3D图形。有很多在线示例可供使用(包括rgl文档)。
R-Wiki提供了一个很好的示例,介绍如何使用rgl绘制3D散点图。
GGobi
另一个值得了解的软件包是rggobi。有一本Springer书籍介绍,还有很多很棒的在线文档和示例,包括在"Looking at Data" 课程中。
我真的很喜欢点图(doplot),当我向别人推荐它们解决数据问题时,他们总是感到惊喜和高兴。尽管点图非常实用,但它们似乎并没有得到广泛应用,我不知道为什么。
以下是Quick-R中的一个例子:
我相信Cleveland在点图的发展和传播方面起了主要作用,他的书中的示例(其中可以轻松检测出错误数据)是使用它们的有力论据。请注意,上面的示例只在每行放置一个点,而它们的真正威力在于每行有多个点,并且使用图例来解释每个点的含义。例如,您可以为三个不同的时间点使用不同的符号或颜色,然后轻松地了解不同类别中的时间模式。
在以下示例中(使用了Excel!),您可以清楚地看到哪个类别可能遭受了标签交换的影响。
使用极坐标绘制图表确实被低估了——一些人可能会说这是有道理的。我认为,能够证明使用它们的情况并不常见;同时,当这些情况出现时,极坐标图表可以展示线性图表无法展示的数据模式。
我认为这是因为有时候您的数据固有地是极坐标而不是线形——例如,它是循环的(x 坐标表示在多个日子内一天中的时间),或者数据先前映射到了极性特征空间。
下面是一个例子。该图显示了一个网站每小时的平均流量。请注意,在晚上 10 点和凌晨 1 点有两个峰值。对于网站的网络工程师来说,这些峰值非常重要;同样重要的是它们在相互靠近 (仅相隔两个小时)。但是,如果将相同数据绘制在传统坐标系上,则此模式将完全隐藏——以线性方式绘制,这两个峰值将相隔20个小时,虽然它们也是在连续的两天内相隔仅两个小时。上面的极坐标图表以简洁和直观的方式展示了这一点(不需要图例)。
有两种方法(我知道的)可以使用 R 创建此类图表(我使用 R 创建了上面的图表)。其中一种是在基础或网格图形系统中编写自己的函数。另一种更简单的方法是使用circular包。您将使用的函数是'rose.diag':
data = c(35, 78, 34, 25, 21, 17, 22, 19, 25, 18, 25, 21, 16, 20, 26,
19, 24, 18, 23, 25, 24, 25, 71, 27)
three_palettes = c(brewer.pal(12, "Set3"), brewer.pal(8, "Accent"),
brewer.pal(9, "Set1"))
rose.diag(data, bins=24, main="Daily Site Traffic by Hour", col=three_palettes)
qplot(y=data, x=1:length(data), fill=factor(1:length(data)), stat='identity', geom='bar') + coord_polar()
- naught101如果散点图上的点过多,导致图像混乱不清,尝试使用平滑散点图。以下是一个示例:
library(mlbench) ## this package has a smiley function
n <- 1e5 ## number of points
p <- mlbench.smiley(n,sd1 = 0.4, sd2 = 0.4) ## make a smiley :-)
x <- p$x[,1]; y <- p$x[,2]
par(mfrow = c(1,2)) ## plot side by side
plot(x,y) ## left plot, regular scatter plot
smoothScatter(x,y) ## right plot, smoothed scatter plot
推荐使用 @Dirk Eddelbuettel 提出的 hexbin
软件包来达到相同的目的,但 smoothScatter()
有一个优点,它属于 graphics
软件包,并因此是标准的 R 安装的一部分。
关于sparkline和其他Tufte思想,YaleToolkit软件包在CRAN上提供了函数sparkline
和sparklines
。
另一个适用于大型数据集的软件包是hexbin,它巧妙地将数据分成桶以处理可能对简单散点图过大的数据集。
我也喜欢Tufte对箱线图的修改,因为它们在水平方向上非常“窄”,不会用冗余的线条使绘图变得混乱,这让你可以更轻松地进行小规模比较。但是,这种方法最适合具有相当数量类别的情况;如果您在图表中只有几个类别,则通常(Tukey)的箱线图看起来更好,因为它们的线条更加粗实。
library(lattice)
library(taRifx)
compareplot(~weight | Diet * Time * Chick,
data.frame=cw ,
main = "Chick Weights",
box.show.mean=FALSE,
box.show.whiskers=FALSE,
box.show.box=FALSE
)
有其他制作这种图表的方法(包括另一种Tufte箱线图),可以在这个问题中讨论。
我们不应该忘记可爱且(历史上)重要的茎叶图(Tufte 也很喜欢!)。您可以直接获得数据密度和形状的数字概述(当然,如果数据集不超过约200个点)。在 R 中,函数stem
会在工作区中生成您的茎叶显示。我更喜欢使用来自fmsb包的gstem
函数将其直接绘制到图形设备中。下面是海狸体温变异(数据应位于默认数据集中)的茎-叶显示:
require(fmsb)
gstem(beaver1$temp)