如何使用ggplot绘制彩色轮?

9
我正在阅读《ggplot2-数据分析的优雅图形》(Wickham,2009),第32页的“缩放”部分如下所述:
缩放涉及将数据值映射到此空间中的点。有许多方法可以做到这一点,但是在这里,由于cyl是一个分类变量,我们将值映射到色轮上均匀间隔的颜色上,如图3.4所示。当变量为连续变量时使用不同的映射。这些转换的结果如表3.4所示,其中包含计算机可理解的值。
该书没有详细解释如何获得此表3.4,更不用说图3.4了。内置数据库是mpg。有人知道如何获得此表和图吗? 谢谢。

1
至于表格,它是在数据空间和美学空间之间进行翻译时幕后所做的工作的示例。该表格并不存在于任何地方,但是ggplot_build(qplot(displ, hwy, data=mpg, colour=factor(cyl)))$data[[1]]相对接近(并基于挖掘ggplot的工作原理)。 - Brian Diggs
2个回答

11

想知道如何在不使用coord_polar()的情况下完成此操作,因为来自Wickham书中的示例显然没有这样做。结果证明,您只需使用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。


干得好!数据框gg可以为您提供十六进制颜色表,无需额外操作。我尝试使用501个x和y点运行了您的代码,这使圆的边缘变得平滑,并且运行非常快速。 - eipi10
干得好!jlhoward。但是还有一个问题:mpg$cyl的因子(factor(mpg$cyl))与书中提到的并展示在图3.4中的这个图形有什么关系吗? - Ουιλιαμ Αρκευα
好的,factor(mpg$cyl) 有4个级别,在Wickham的书中的图表上显示了5个颜色点,所以我不理解它们之间的联系。然而,我在上面提到的问题的回答中展示了如何为给定数量的级别派生颜色。这只是该过程的图形表示。 - jlhoward

10

这与您想要的接近,但颜色过渡可能不够平滑。希望其他人能进一步改进:

代码修改自此处

# 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)))

通过使用更细的网格来定义hs值,可以获得更平滑的颜色过渡效果,但绘制图表需要很长时间。您可以通过将v的值设置在0到1之间来改变亮度。(根据@BrodieG的评论,将v= 1/2以获得Hadley's ggplot2书中图形的亮度级别。)

下面是一个版本的图表,使用0.001的步幅来定义h值(同时保持s的步幅为0.05)。这个图花费了几分钟来在我的比较新的Macbook Pro上绘制,但是h坐标轴上的颜色过渡相当平滑:

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

这里输入图片描述

要获得颜色表,您可以使用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
我认为您需要在1/2最大亮度处使用恒定的V值来复制该图像。 - BrodieG

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接