Create an image filled chart in R using ggplot [duplicate]

别说谁变了你拦得住时间么 提交于 2019-12-23 04:33:10

问题


I'm trying to create a chart like the below image; essentailly its a filled shape denoting a percentage (most likely an image of a human, but this could be anything theortically).

I've managed to do this is Excel, albeit with a lot of botching of bar charts. But is there a way to do this in R, preferably using ggplot?

I've read the similar question Use an image as area fill in an R plot which doesn't quite do the same thing, but I cannot envisage a solution using this method.

Any help is appreciated!

EDIT:

As pointed out, this has been answered using plotly: Use a custom icon in plotly's pie chart. Is this possible to do with ggplot?

Note I stole this image from a google image search for infographics.


回答1:


You really only need to modify the plotting command from the answer that @PoGibas linked: 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")



来源:https://stackoverflow.com/questions/48522350/create-an-image-filled-chart-in-r-using-ggplot

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!