r - Can I recreate this polar coordinate spider chart in plotly? -


i'm having bit of difficulty figuring out how recreate following graphic of spider (or radar) chart, using plotly. actually, can't recreate in recent versions of ggplot2 because there have been breaking changes since 1.0.1.

here's example graphic:

enter image description here

here's original function built it:

http://pcwww.liv.ac.uk/~william/geodemographic%20classifiability/func%20createradialplot.r

here's example of how original function worked:

http://rstudio-pubs-static.s3.amazonaws.com/5795_e6e6411731bb4f1b9cc7eb49499c2082.html

here's not dummy data:

d <- structure(list(year = rep(c("2015","2016"),each=24),                     response = structure(rep(1l:24l,2),                                           .label = c("trustworthy", "supportive", "leading",                                                     "strong", "dependable", "consultative",                                                     "knowledgeable", "sensible",                                                      "intelligent", "consistent", "stable",                                                      "innovative", "aggressive",                                                      "conservative", "visionary",                                                      "arrogant", "professional",                                                      "responsive", "confident", "accessible",                                                      "timely", "focused", "niche", "none"),                                          class = "factor"),                      proportion = c(0.54, 0.48, 0.33, 0.35, 0.47, 0.3, 0.43, 0.29, 0.36,                                    0.38, 0.45, 0.32, 0.27, 0.22, 0.26,0.95, 0.57, 0.42,                                     0.38, 0.5, 0.31, 0.31, 0.12, 0.88, 0.55, 0.55, 0.31,                                    0.4, 0.5, 0.34, 0.53, 0.3, 0.41, 0.41, 0.46, 0.34,                                     0.22, 0.17, 0.28, 0.94, 0.62, 0.46, 0.41, 0.53, 0.34,                                     0.36, 0.1, 0.84), n = rep(c(240l,258l),each=24)),                .names = c("year", "response", "proportion", "n"),                 row.names = c(na, -48l), class = c("tbl_df", "tbl", "data.frame")) 

here's attempt (not good)

plot_ly(d, r = proportion, t = response, x = response,          color = factor(year), mode = "markers") %>% layout(margin = list(l=50,r=0,b=0,t=0,pad = 4), showlegend = true) 

any thoughts on how might able recreate using plotly?

the options available polar plots still limited. there not, far can tell, way add text polar plot category labels around circumference. neither text scatter points, nor annotations nor tick labels (except @ 4 quarter points) compatible polar coordinates in plotly @ moment.

so, need little creative.

one type of polar coordinate system work nicely projected map of sperical earth using azimuthal projection. here demonstration of how might adapt problem.

first, convert values plot latitude , longitudes centred on south pole:

scale <- 10   # multiply latitudes factor of 10 scale plot size in initial view d$lat <- scale*d$proportion - 90 d$long <- (as.numeric(d$response)-1) * 360/24 

plot using azimuthal equidistant projection

p <- plot_ly(d[c(1:24,1,25:48,25),], lat=lat, lon=long, color = factor(year), colors=c('#f8756b','#00bdc2'),              type = 'scattergeo', mode = 'lines+markers', showlegend=t) %>% layout(geo = list(scope='world', showland=f, showcoastlines=f, showframe=f,              projection = list(type = 'azimuthal equidistant', rotation=list(lat=-90), scale=5)),               legend=list(x=0.7,y=0.85)) 

put labels on

p %<>% add_trace(type="scattergeo",  mode = "text", lat=rep(scale*1.1-90,24), lon=long,                   text=response, showlegend=f, textfont=list(size=10)) %>%        add_trace(type="scattergeo",  mode = "text", showlegend=f, textfont=list(size=12),                  lat=seq(-90, -90+scale,length.out = 5), lon=rep(0,5),                   text=c("","25%","50%","75%","100%")) 

finally, add grid lines

l1 <- list(width = 0.5, color = rgb(.5,.5,.5), dash = "3px") l2 <- list(width = 0.5, color = rgb(.5,.5,.5)) (i in c(0.1, 0.25, 0.5, 0.75, 1))      p <- add_trace(lat=rep(-90, 100)-scale*i, lon=seq(0,360, length.out=100), type='scattergeo', mode='lines', line=l1, showlegend=f, evaluate=t) (i in 1:24)      p <- add_trace(p,lat=c(-90+scale*0.1,-90+scale), lon=rep(i*360/24,2), type='scattergeo', mode='lines', line=l2, showlegend=f, evaluate=t) 

enter image description here

update plotly version 4.x

breaking changes in updates plotly mean original version no longer works without few modifications bring date. here updated version:

library(data.table) gridlines1 = data.table(lat = -90 + scale*(c(0.1, 0.25, 0.5, 0.75, 1))) gridlines1 = gridlines1[, .(long = c(seq(0,360, length.out=100), na)), = lat] gridlines1[is.na(long), lat := na]  gridlines2 = data.table(long = seq(0,360, length.out=25)[-1]) gridlines2 = gridlines2[, .(lat = c(na, -90, -90+scale, na)), = long] gridlines2[is.na(lat), long := na]  text.labels = data.table(   lat=seq(-90, -90+scale,length.out = 5),   long = 0,   text=c("","25%","50%","75%","100%"))  p = plot_ly() %>% add_trace(type="scattergeo", data = d[c(1:24, 1, 25:48, 25),],        lat=~lat, lon=~long,        color = factor(d[c(1:24, 1, 25:48, 25),]$year),        mode = 'lines+markers')%>% layout(geo = list(scope='world', showland=f, showcoastlines=f, showframe=f,     projection = list(type = 'azimuthal equidistant', rotation=list(lat=-90), scale=5)),      legend = list(x=0.7, y=0.85)) %>% add_trace(data = gridlines1, lat=~lat, lon=~long,      type='scattergeo', mode='lines', line=l1,      showlegend=f, inherit = f)  %>% add_trace(data = gridlines2, lat=~lat, lon=~long,     type='scattergeo', mode='lines', line=l2, showlegend=f) %>% add_trace(data = text.labels, lat=~lat, lon=~long,    type="scattergeo", mode = "text", text=~text, textfont = list(size = 12),     showlegend=f, inherit=f) %>% add_trace(data = d, lat=-90+scale*1.2, lon=~long,      type="scattergeo", mode = "text", text=~response, textfont = list(size = 10),     showlegend=f, inherit=f)   p