【问题标题】:Customizing aesthetics of faceted barplot自定义多面条形图的美学
【发布时间】:2011-06-09 18:44:53
【问题描述】:

我正在尝试用 R 中的一些 ggplots 对最近的 MLB 选秀进行一些分析

selection <- draft[c("Team","Division","Position")]
head(selection)

  Team   Division Position
1  pit NL Central        P
2  sea AL West           P
3  ari NL West           P
4  bal AL East           P
5  kc  AL Central        O
6  was NL East           I

其中 P = 投手,O=外场等

我想按每个分区的位置显示球队选择的球员人数

p <- ggplot(data=selection, aes(x=Team, fill= Position))  + geom_bar(position="stack")
p <-  p + coord_flip()
p <- p+ ylab("Players Selected")
p <- p + facet_wrap(~Division)
p

这让我了解了其中的一部分,但很不吸引人

a) 分组有效,但所有团队都显示在每个分区网格中 - 尽管每个分区中只有 5 或 6 个团队实际上 - 并且正确 - 显示数据

b) 通过坐标翻转,团队将按字母倒序排列在页面下方。我可以求助吗?左对齐也很好

c) 我如何将图例设置为 Pitching、Outfield 而不是 P 和 O - 这是我需要以某种方式设置和包含的向量

d) 看看每支球队选择对每种类型球员的比例也会很有趣。这是通过设置 position="fill" 来完成的。我可以将轴设置为 % 而不是 0 到 1。我还尝试设置 geom_vline(aes(xintercept=0.5) - 和 yintercept 以防考虑到翻转 - 但这条线没有出现在 x 轴的中间标记处

帮助非常感谢

【问题讨论】:

  • 如果您的目标只是翻转因子,您可以在 ggplot2 aes 调用 x= 时使用 reorder(Team, -as.numeric(Team))

标签: r ggplot2 aesthetics


【解决方案1】:

编辑:在获取数据(并将其存储在名为 mlbtmp.txt 的文本文件中)和更多实验之后,完成改造,包括来自其他答案的信息:

selection <- read.table("mlbtmp.txt",skip=1)
names(selection) <- c("row","League","Division","Position","Team")
## arrange order/recode factors
selection <- transform(selection,
       Team=factor(Team,levels=rev(levels(Team))),
                   Position=factor(Position,levels=c("P","I","C","O"),
                                  labels=c("Pitching","Infield",
                                    "Center","Outfield")))

我玩弄了facet_gridfacet_wrapscalescoord_flip 等的各种排列。有些按预期工作,有些则没有:

library(ggplot2)
p <- ggplot(data=selection, aes(x=Team, fill= Position))  +
  geom_bar(position="stack")
p + facet_grid(.~Division,scales="free_x") + coord_flip()  ## OK

## seems to fail with either "free_x" or "free_y"
p + facet_grid(Division~.,scales="free") + coord_flip()

## works but does not preserve 'count' axis:
p + facet_wrap(~Division,scales="free")

我最终得到facet_wrap(...,scales="free") 并使用ylim 来约束轴。

p + facet_wrap(~Division,scales="free") + coord_flip() +
  ylim(0,60) + opts(axis.text.y=theme_text(hjust=0))

原则上可能有一种方法可以使用..density....ncount....ndensity..stat_bin 计算的其他统计信息之一,而不是默认的..count..,但我找不到有效的组合。

相反(当卡住 ggplot 的即时转换时,这通常是最好的解决方案)我自己重新塑造了数据:

## pull out Team identification within Division and League
stab <- unique(subset(selection,select=c(Team,Division,League)))
## compute proportions by team
s2 <- melt(ddply(selection,"Team",function(x) with(x,table(Position)/nrow(x))))
## fix names
s2 <- rename(s2,c(variable="Position",value="proportion"))
## merge Division/League info back to summarized data
s3 <- merge(s2,stab)

p2 <- ggplot(data=s3, aes(x=Team, fill= Position,y=proportion))  +
  geom_bar(position="stack")+scale_y_continuous(formatter="percent")+
  geom_hline(yintercept=0.5,linetype=3)+ facet_wrap(~Division,scales="free") +
  opts(axis.text.y=theme_text(hjust=0))+coord_flip()

这里显然可以做更多的美化工作,但这应该能让你大部分时间到达那里......

【讨论】:

  • a) 显示正确的数据,但球队轴只显示第一分区的五支球队
  • 如果您使用 dput() 包含大部分数据,我们会更容易为您提供帮助。
  • 嗯。您是否可以通过使用dput 或将数据放在网络上的某个地方并发布 URL 来发布可能很小但足够完整的数据子集(即,可重现的示例)? (我错过了joran的评论,基本相同)
  • 不熟悉 dput() 但会在帮助下尝试。否则我可能会在网络上发布一些数据
  • 试试这个link获取数据
【解决方案2】:

填补@Ben Bolker 回答中的一些空白...

要对团队进行不同的排序,您需要将该列存储为一个因素。可能不会有一种简短、快速的方法来指定您想要的顺序,因为您很可能希望分别对每个部门的团队进行排序。这意味着您需要对所有个团队进行排序,以便每个分区子集保持正确排序。类似的东西(这是示意图,语法不正确):

selection$Team <- factor(selection$Team,
    levels=c( (AL East teams in desired order), 
              (AL Central teams in desire order), etc))

根据您计算的其他内容,可能有一种快速的方法来指定它,或者您可能必须手动将它们写出来。

轴文本对齐方式可以通过

修改
opts(axis.text.x=theme_text(hjust=1))

后退一步,请注意,使用 ggplot2 的解决方案通常是通过修改用于构建绘图的 data 而不是绘图本身来找到的。这是一种不同的思考方式,但一旦习惯了它就会很方便。

【讨论】:

  • 看起来不错,但我认为您实际上并不需要有序因子——ggplot 按水平顺序绘制因子,无论它们是否有序......(我是不是 100% 确定这一点,但测试会相当简单)
  • 感谢 Joran 的洞察力,特别是关于修改数据的见解
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-16
  • 2017-01-15
  • 2021-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多