7

I was wondering if there's a way to have a custom icon for plotly's pie chart instead of the usual pie division

As of now I'm displaying the gender information using a pie chart which looks as below:

enter image description here

I'm trying to make it look like the gender plot in the link below:

https://app.displayr.com/Dashboard?id=c1506180-fe64-4941-8d24-9ec4a54439af#page=3e133117-f3b2-488b-bc02-1c2619cf3914

enter image description here

The plotly code is as under:

plot_ly(genderselection, labels = ~Gender, values = ~Freq, type = 'pie') %>%
      layout(title = paste0("Gender Distribution of Patients from Boston"),
             xaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE),
             yaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE),
             legend=list(orientation='h'))

The genderselection dataframe:

  Gender Freq
     F   70
     M   65

If not using plotly is there any other library that can be used to display information using custom icons ?

byouness
  • 1,746
  • 2
  • 24
  • 41
Dollar Vora
  • 197
  • 1
  • 10

1 Answers1

8

(1) Download the png file available here and save it in your working directory as man_woman.png
(2) Run the following code:

library(png)
library(plotly)

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

# Load png file with man and woman
img <- readPNG("man_woman.png")
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
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

# Plot matrix using heatmap and print text
labs <- c(paste0(pcts[2], "% Males"),paste0(pcts[1], "% Females"))
ax <- list(ticks='', showticklabels=FALSE, showgrid=FALSE, zeroline=FALSE)
p <- plot_ly(z = imgmtx, showscale=FALSE, type='heatmap', width = 500,  height = 500) %>%
     add_text(x = c(100,250), y = c(20,20), type='heatmap', mode="text",
        text=labs, showlegend=FALSE, textfont=list(size=20, color="#FFFFFF"), inherit=FALSE) %>%
     layout(xaxis = ax,  yaxis = ax)  
p

enter image description here

Marco Sandri
  • 23,289
  • 7
  • 54
  • 58
  • This is exactly what I was looking for ! Thanks ! Is there a way to change the background to white and the color fill ? I do see you filled the bodies with different colors according to the percentages but does it take the filled colors by default ? Can we define the colors as per our choice? – Dollar Vora Oct 06 '17 at 13:28
  • 1
    @DollarVora Here you can find a way to control color palette for the plotly `heatmap`: https://stackoverflow.com/questions/44918709/how-to-generate-a-custom-color-scale-for-plotly-heatmap – Marco Sandri Oct 06 '17 at 13:53
  • I know this is an old post but I had the same follow up question. Here's how you can do it ````palette <- colorRampPalette(c(rgb(48, 58, 63, 1, maxColorValue = 255), rgb(204, 204, 204, 1, maxColorValue = 255), rgb(7, 200, 200, 1, maxColorValue = 255)))```` then use this in plot_ly ````plot_ly(z = imgmtx, showscale=FALSE, type='heatmap', width = 500, height = 500, colors = palette(50))```` – Mr.Rlover Mar 19 '20 at 07:45