如何使用ggplot绘制色轮?

How to plot a colour wheel by using ggplot?

提问人:Ουιλιαμ Αρκευα 提问时间:2/1/2014 最后编辑:eipi10Ουιλιαμ Αρκευα 更新时间:12/13/2015 访问量:4601

问:

我正在阅读“ggplot2 - Elegant Graphics for Data Analysis”(Wickham,2009)一书,“缩放”部分(第 32 页)是这样说的:

然后,缩放涉及将数据值映射到此空间中的点。 有很多方法可以做到这一点,但在这里,因为 cyl 是分类的 变量 我们将值映射到色轮上均匀分布的色调,如 如图 3.4 所示。当变量 连续的。这些转换的结果如表 3.4 所示,其中 包含对计算机有意义的值。

enter image description here

enter image description here

书中没有详细解释如何得到这个表3.4,更不用说图3.4了。内置数据库是 mpg。有人知道如何获得这个表格和图表吗? 提前致谢。

R 图形 颜色 ggplot2

评论

1赞 Brian Diggs 2/1/2014
至于表格,它是在数据空间和审美空间之间转换的幕后工作的一个例子。该表在任何地方都不存在这种形式,但有些接近(并且基于对 ggplot 工作原理的深入研究)。ggplot_build(qplot(displ, hwy, data=mpg, colour=factor(cyl)))$data[[1]]

答:

10赞 eipi10 2/1/2014 #1

这接近您要查找的内容,但颜色过渡可能不够平滑。希望其他人可以改进这一点:

代码改编自此处

# Create hsv grid
d = expand.grid(h=seq(0,1,0.01), s=seq(0,1,0.05), v=1)

p1 = ggplot() +
          coord_polar(theta="x") +
          scale_x_continuous(breaks=NULL) +
          scale_y_continuous(breaks=NULL) +
          scale_fill_identity() +
          geom_rect(data=d, mapping=aes(xmin=h, xmax=h+resolution(h), 
                                        ymin=s, ymax=s+resolution(s), 
                                        fill=hsv(h,s,v)))

您可以通过对 和 值使用更精细的网格来获得更平滑的颜色过渡,但渲染绘图需要很长时间。您可以通过将值设置为介于 0 和 1 之间的值来更改亮度。(根据 @BrodieG 的评论,设置 v=1/2 以获得 Hadley 的 ggplot2 书中人物的亮度级别。hsv

下面是使用步长为 0.001 的值(同时将步长保持在 0.05)的图版本。在我相对较新的Macbook Pro上渲染花了几分钟时间,但沿坐标的过渡非常平滑:hsh

png("Colour wheel.png", 2000, 2000) 
p1
dev.off()

enter image description here

若要获取颜色表,可以使用返回十六进制颜色值的函数。例如:hsv()

# Make up some hsv colors
colors = data.frame(h=seq(0.1,0.5,length.out=6), 
                    s=seq(0.5,0.9,length.out=6), 
                    v=c(.5,.5,.5,.9,.9,.9))

# Convert to hexadecimal
apply(colors, 1, function(x) hsv(x[1],x[2],x[3]))
[1] "#806640" "#7A8036" "#50802B" "#3CE642" "#29E68B" "#17E6E6"

# Plot them to see what they look like
plot(1:6,rep(1,6), pch=15, cex=5, col=apply(colors, 1, function(x) hsv(x[1],x[2],x[3])))

评论

1赞 BrodieG 2/1/2014
+1.我认为您需要在 1/2 最大亮度下使用恒定的 V 值来复制图像。
11赞 jlhoward 2/1/2014 #2

想知道如何在没有的情况下做到这一点,因为 Wickham 书中的例子显然没有。事实证明,你可以只使用.coord_polar()geom_point(...)

library(ggplot2)
r  <- seq(0,1,length=201)
th <- seq(0,2*pi, length=201)
d  <- expand.grid(r=r,th=th)
gg <- with(d,data.frame(d,x=r*sin(th),y=r*cos(th),
                        z=hcl(h=360*th/(2*pi),c=100*r, l=65)))
ggplot(gg) +
  geom_point(aes(x,y, color=z), size=3)+
  scale_color_identity()+labs(x="",y="") +
  coord_fixed()

这将在几秒钟内呈现。此参考指出默认亮度 l=65。

评论

0赞 eipi10 2/1/2014
干得好!数据框为您提供十六进制颜色表,无需任何额外工作。我用 501 x 和 y 点尝试了您的代码,这平滑了圆圈的边缘,并且仍然运行得很快。gg
0赞 Ουιλιαμ Αρκευα 2/2/2014
干的好!JLHOWARD的。但仍然存在一个问题:因子(mpg$cyl)与图3.4中提到的该图的获得方式之间是否存在任何关系?
0赞 jlhoward 2/2/2014
嗯,有 4 个级别,威克姆书中的情节在色轮上显示了 5 个点,所以不,我不明白其中的联系。不过,对我上面链接的问题的回答显示了给定数量的级别的颜色是如何派生的。这只是该过程的图形表示。factor(mpg$cyl)