使用ggplot

时间:2018-01-30 13:14:13

标签: r ggplot2 data-visualization

我正在尝试创建一个类似下图的图表;它本身就是一个填充的形状,表示一个百分比(很可能是一个人的形象,但这可能是任何理论上的)。

我设法做到这一点就是Excel,虽然有很多条形图。但有没有办法在R中执行此操作,最好使用ggplot?

我已经阅读了类似的问题Use an image as area fill in an R plot但它并没有做同样的事情,但我无法想象使用这种方法的解决方案。

感谢任何帮助!

修改

正如所指出的那样,已经使用剧情来回答:Use a custom icon in plotly's pie chart这可能与ggplot有关吗?

Example chart

注意我从谷歌图片搜索图表中偷了这张图片。

1 个答案:

答案 0 :(得分:1)

你真的只需要修改@PoGibas链接的答案中的绘图命令:here


library(png)
library(ggplot2)

genderselection <- read.table(text="
  Gender Freq
                              F   70
                              M   30
                              ", header=T)
pcts <- round(prop.table(genderselection$Freq)*100)

# Load png file from imgur as binary
con <- url("https://i.imgur.com/vFDSFYX.png",
           open='rb')
rawpng <- readBin(con, what='raw', n=50000)
close(con)

img <- readPNG(rawpng)
h <- dim(img)[1]
w <- dim(img)[2]

# Find the rows where feet starts and head ends
pos1 <- which(apply(img[,,1], 1, function(y) any(y==1)))
mn1 <- min(pos1)
mx1 <- max(pos1)
pospctM <- round((mx1-mn1)*pcts[2]/100+mn1)
pospctF <- round((mx1-mn1)*pcts[1]/100+mn1)

# Fill bodies with a different color according to percentages
# Note that this relies on the fact that the png is a bitmap.
# The png is expressed as a matrix with a cell for each pixel
# and 3 layers for r,g,b.
dim(img)
#> [1] 360 360   3

# Create a 2d matrix by just taking the red values
# Image is black and white so black corresponds to 0
# white corresponds to 1. Then change the values of
#  the cells to correspond to one of three categories.
imgmtx <- img[h:1,,1]
whitemtx <- (imgmtx==1)
colmtx <- matrix(rep(FALSE,h*w),nrow=h)
midpt <- round(w/2)-10
colmtx[mx1:pospctM,1:midpt] <- TRUE
colmtx[mx1:pospctF,(midpt+1):w] <- TRUE
imgmtx[whitemtx & colmtx] <- 0.5

# Need to melt the matrix into a data.frame that ggplot can understand
df <- reshape2::melt(imgmtx)
head(df)
#>   Var1 Var2 value
#> 1    1    1     0
#> 2    2    1     0
#> 3    3    1     0
#> 4    4    1     0
#> 5    5    1     0
#> 6    6    1     0

cols <- c(rgb(255,255,255,maxColorValue = 255),
          rgb(209,230,244,maxColorValue = 255), 
          rgb(42,128,183,maxColorValue = 255))

# Then use a heatmap with 3 colours for background, and percentage fills
# Converting the fill value to a factor causes a discrete scale.
# geom_tile takes three columns: x, y, fill corresponding to 
# x-coord, y-coord, and colour of the cell.
ggplot(df, aes(x = Var2, y = Var1, fill = factor(value)))+
  geom_tile() +
  scale_fill_manual(values = cols) +
  theme(legend.position = "none")