如何在r中的ggplot中绘制两个半圆 [英] how to draw two half circles in ggplot in r

查看:533
本文介绍了如何在r中的ggplot中绘制两个半圆的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我怎样才能做出这样的情节,用两个不同大小的半圆(或其他形状,如三角形等)?



我研究了一些选项:另一篇文章使用一些unicode符号建议,这对我没用。如果我使用矢量图像,如何正确调整大小参数,以便两个圆圈相互接触?



示例数据(我想使大小这两个半圆等于 circle1size circle2size ):

  df = data.frame(circle1size = c(1,3,2),
circle2size = c(3,6,5),
middlepointposition = c(1,2,3))

最终有一种方法来定位半圆在不同的y值,编码第三维,像这样?



任何建议都是非常值得赞赏的。

解决方案

你要求的是极坐标中的条形图。这可以在ggplot2中轻松完成。请注意,我们需要映射 y = sqrt(count)以获得与计数成比例的半圆区域。

  df < -  data.frame(x = c(1,2),
type = c(Investors,Assignees),
count = c(19419,1132))

ggplot(df,aes(x = x,y = sqrt(count),fill = type))+ geom_col(width = 1)+
scale_x_discrete(expand = c(0,0),limits = c(0.5,2.5))+
coord_polar(theta =x,direction = -1)



进一步的造型必须用于删除灰色背景,删除坐标轴,更改颜色等,但这都是标准ggplot2。



更新1:

  df < -  data.frame(x = rep(c(1,2),3 ),
类型= rep(c(投资者,受让人),3),
国家= rep(c(日本,德国,韩国),每个= 2),
计数= c(19419,1132,8138,947,8349,436))

df $ country < - factor(df $ country,levels = c(Japan,Germany, )()= geom_col(width = 1)+
scale_x_continuous(expand =))

ggplot(df,aes(x = x,y = sqrt(count) c(0,0),limits = c(0.5,2.5))+
scale_y_continuous(expand = c(0,0))+
coord_polar(theta =x,direction = -1) +
facet_wrap(〜country)+
theme_void()



更新2:在不同位置绘制个别图。



我们可以利用一些技巧来获取单独的图并将它们绘制在附近的不同位置剧情。这是有效的,并且是一种可以用任何类型的情节完成的通用方法,但这可能是过度的。无论如何,这里是解决方案。

  library(tidyverse)#for map 
library(cowplot)#for draw_text, draw_plot,get_legend,insert_yaxis_grob

#国家数据的数据帧
df < - data.frame(x = rep(c(1,2),3),
类型=代表(投资者,受让人),3),
国家=代表(c(日本,德国,韩国),每个= 2),
计数= c(19419,1132,8138,947,8349,436))

#坐标列表
coord_list = list(Japan = c(1,3),Germany = c(2 ,1),韩国= c(3,2))

#制作单个地块列表
split(df,df $ country)%>%
地图(〜 ggplot(。,aes(x = x,y = sqrt(count),fill = type))+ geom_col(width = 1)+
scale_x_continuous(expand = c(0,0),limits = c(0.5 ,2.5))+
scale_y_continuous(expand = c(0,0),limits = c(0,160))+
draw_text(。country [1],1,160,vjust = 0 )+
coord_polar(theta =x,start = 3 * pi / 2)+
guides(fill = guide_l egend(title =Type,reverse = T))+
theme_void()+ theme(legend.position =none)) - > plotlist

#提取图例
legend< - get_legend(plotlist [[1]] + theme(legend.position =right))

#现在绘制我们想要它们的地块
width = 1.3
height = 1.3
p <-ggplot()+ scale_x_continuous(limits = c(0.5,3.5))+ scale_y_continuous(limits = c (0.5,3.5))
(姓名国家(coord_list)){
p < - p + draw_plot(plotlist [[country]],x = coord_list [[country]] [1] - width / 2,
y = coord_list [[country]] [2] -height / 2,
width = width,height = height)
}


$ b#与图例一起绘制
ggdraw(insert_yaxis_grob(p,legend))


How can I make a plot like this with two different-sized half circles (or other shapes such as triangles etc.)?

I've looked into a few options: Another post suggested using some unicode symbol, that didn't work for me. And if I use a vector image, how can I properly adjust the size parameter so the 2 circles touch each other?

Sample data (I would like to make the size of the two half-circles equal to circle1size and circle2size):

df = data.frame(circle1size = c(1, 3, 2),
                circle2size = c(3, 6, 5),
                middlepointposition = c(1, 2, 3))

And ultimately is there a way to position the half-circles at different y-values too, to encode a 3rd dimension, like so?

Any advice is much appreciated.

解决方案

What you're asking for is a bar plot in polar coordinates. This can be done easily in ggplot2. Note that we need to map y = sqrt(count) to get the area of the half circle proportional to the count.

df <- data.frame(x = c(1, 2),
                 type = c("Investors", "Assignees"),
                 count = c(19419, 1132))

ggplot(df, aes(x = x, y = sqrt(count), fill = type)) + geom_col(width = 1) +
  scale_x_discrete(expand = c(0,0), limits = c(0.5, 2.5)) +
  coord_polar(theta = "x", direction = -1)

Further styling would have to be applied to remove the gray background, remove the axes, change the color, etc., but that's all standard ggplot2.

Update 1: Improved version with multiple countries.

df <- data.frame(x = rep(c(1, 2), 3),
                 type = rep(c("Investors", "Assignees"), 3),
                 country = rep(c("Japan", "Germany", "Korea"), each = 2),
                 count = c(19419, 1132, 8138, 947, 8349, 436))

df$country <- factor(df$country, levels = c("Japan", "Germany", "Korea"))

ggplot(df, aes(x=x, y=sqrt(count), fill=type)) + geom_col(width =1) +
  scale_x_continuous(expand = c(0, 0), limits = c(0.5, 2.5)) +
  scale_y_continuous(expand = c(0, 0)) +
  coord_polar(theta = "x", direction = -1) +
  facet_wrap(~country) +
  theme_void()

Update 2: Drawing the individual plots at different locations.

We can do some trickery to take the individual plots and plot them at different locations in an enclosing plot. This works, and is a generic method that can be done with any sort of plot, but it's probably overkill here. Anyways, here is the solution.

library(tidyverse) # for map
library(cowplot) # for draw_text, draw_plot, get_legend, insert_yaxis_grob

# data frame of country data
df <- data.frame(x = rep(c(1, 2), 3),
                 type = rep(c("Investors", "Assignees"), 3),
                 country = rep(c("Japan", "Germany", "Korea"), each = 2),
                 count = c(19419, 1132, 8138, 947, 8349, 436))

# list of coordinates
coord_list = list(Japan = c(1, 3), Germany = c(2, 1), Korea = c(3, 2))

# make list of individual plots
split(df, df$country) %>% 
  map( ~ ggplot(., aes(x=x, y=sqrt(count), fill=type)) + geom_col(width =1) +
  scale_x_continuous(expand = c(0, 0), limits = c(0.5, 2.5)) +
  scale_y_continuous(expand = c(0, 0), limits = c(0, 160)) +
  draw_text(.$country[1], 1, 160, vjust = 0) +
  coord_polar(theta = "x", start = 3*pi/2) +
  guides(fill = guide_legend(title = "Type", reverse = T)) +
  theme_void() + theme(legend.position = "none") ) -> plotlist

# extract the legend
legend <- get_legend(plotlist[[1]] + theme(legend.position = "right"))

# now plot the plots where we want them
width = 1.3
height = 1.3
p <- ggplot() + scale_x_continuous(limits = c(0.5, 3.5)) + scale_y_continuous(limits = c(0.5, 3.5))
for (country in names(coord_list)) {
  p <- p + draw_plot(plotlist[[country]], x = coord_list[[country]][1]-width/2,
                     y = coord_list[[country]][2]-height/2,
                     width = width, height = height)  
}
# plot without legend
p

# plot with legend
ggdraw(insert_yaxis_grob(p, legend))

Update 3: Completely different approach, using geom_arc_bar() from the ggforce package.

library(ggforce)
df <- data.frame(start = rep(c(-pi/2, pi/2), 3),
                 type = rep(c("Investors", "Assignees"), 3),
                 country = rep(c("Japan", "Germany", "Korea"), each = 2),
                 x = rep(c(1, 2, 3), each = 2),
                 y = rep(c(3, 1, 2), each = 2),
                 count = c(19419, 1132, 8138, 947, 8349, 436))

r <- 0.5
scale <- r/max(sqrt(df$count))

ggplot(df) + 
  geom_arc_bar(aes(x0 = x, y0 = y, r0 = 0, r = sqrt(count)*scale,
                   start = start, end = start + pi, fill = type),
               color = "white") +
  geom_text(data = df[c(1, 3, 5), ],
            aes(label = country, x = x, y = y + scale*sqrt(count) + .05),
            size =11/.pt, vjust = 0)+ 
  guides(fill = guide_legend(title = "Type", reverse = T)) +
  xlab("x axis") + ylab("y axis") +
  coord_fixed() +
  theme_bw()

这篇关于如何在r中的ggplot中绘制两个半圆的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆