Bubble Chart with bubbles aligned along their bott

2019-04-17 12:26发布

Is there a simple way to make a bubble chart in R like this:

enter image description here

I've played around with ggplot with fake data and have gotten this far:

cat<-c("A", "A", "B", "B", "C", "C")
chara<-c("1", "0", "1", "0", "1", "0")
percent<-c(80, 20, 60, 40, 90,10)
xcoord<-c(10,10,11,11,12,12)
ycoord<-c(10,10,10,10,10,10)

DF<-data.frame(cat,chara, percent, xcoord, ycoord)

NewBubbleChart <- ggplot(DF, aes(x = cat, y = "", size = percent, label = NULL, fill = chara), legend = FALSE) +
                    geom_point(color = "grey50", shape = 21, alpha = 0.99) +  
                   #geom_text(size=4) +
                    theme_bw() +
                    scale_size(range = c(5, 20))

NewBubbleChart <- NewBubbleChart +
                    scale_fill_manual(name = "Type",
                                      values = c("darkblue", "lightblue"),
                                      labels = c("0" = "Type 0", "1" = "Type 1"))

I ended up not using the xcoord and ycoord part, but I left it in. I know that a bar chart would work too, but a bubble chart is wanted instead.

标签: r charts
2条回答
贪生不怕死
2楼-- · 2019-04-17 12:40

I'm not exactly sure how you want the chart to look, but you could try playing with gvisBubbleChart in the package googleVis:

library(googleVis)
##
DF <- cbind(
  DF,
  ID=paste0(DF$cat,DF$chara)
)
bChart <- gvisBubbleChart(
  data=DF,
  idvar="ID",
  xvar="xcoord",
  yvar="chara",
  colorvar="cat",
  sizevar="percent",
  options=list(vAxis='{minValue:.8, maxValue:3}')
)
plot(bChart)

enter image description here

查看更多
霸刀☆藐视天下
3楼-- · 2019-04-17 12:49

This seems to come pretty close.

library(ggplot2)
# function to calculate coords of a circle
circle <- function(center,radius) {
  th <- seq(0,2*pi,len=200)
  data.frame(x=center[1]+radius*cos(th),y=center[2]+radius*sin(th))
}
# example dataset, similar to graphic
df <- data.frame(bank=paste("Bank",LETTERS[1:5]),start=1000*(5:1),end=500*(5:1))    
max <- max(df$start)
n.bubbles <- nrow(df)
scale <- 0.4/sum(sqrt(df$start))
# calculate scaled centers and radii of bubbles
radii <- scale*sqrt(df$start)
ctr.x <- cumsum(c(radii[1],head(radii,-1)+tail(radii,-1)+.01))
# starting (larger) bubbles
gg.1  <- do.call(rbind,lapply(1:n.bubbles,function(i)cbind(group=i,circle(c(ctr.x[i],radii[i]),radii[i]))))
text.1 <- data.frame(x=ctr.x,y=-0.05,label=paste(df$bank,df$start,sep="\n"))
# ending (smaller) bubbles
radii <- scale*sqrt(df$end)
gg.2  <- do.call(rbind,lapply(1:n.bubbles,function(i)cbind(group=i,circle(c(ctr.x[i],radii[i]),radii[i]))))
text.2 <- data.frame(x=ctr.x,y=2*radii+0.02,label=df$end)
# make the plot
ggplot()+
  geom_polygon(data=gg.1,aes(x,y,group=group),fill="dodgerblue")+
  geom_path(data=gg.1,aes(x,y,group=group),color="grey50")+
  geom_text(data=text.1,aes(x,y,label=label))+
  geom_polygon(data=gg.2,aes(x,y,group=group),fill="green2")+
  geom_path(data=gg.2,aes(x,y,group=group),color="grey50")+
  geom_text(data=text.2,aes(x,y,label=label), color="white")+
  labs(x="",y="")+scale_y_continuous(limits=c(-0.1,2.5*scale*sqrt(max(df$start))))+
  coord_fixed()+
  theme(axis.text=element_blank(),axis.ticks=element_blank(),panel.grid=element_blank())

So this is a "bubble-in-bubble" chart, which represents the change in a metric (bank market capitalization in your graphic) between two events or times (before and after the economic collapse, in your graphic). In order for this to work the ending condition must be smaller than the starting condition (otherwise the "inner" bubble is larger than the outer bubble).

The trick bit is getting the circles to be aligned along their bottom edges. This is really difficult using geom_point(...), so I chose to just draw circles for the bubbles instead.

I suspect you'll have to tweak the positioning of the text a bit by hand in a real case. If you want multiple rows (as in the graphic), you might consider ggplot facets.

Finally, if you want the circles shaded (e.g. with a color gradient) this is not really what ggplot is intended for: it's possible but IMO much more work than it's worth.

查看更多
登录 后发表回答