[R-sig-Geo] Plotting pie charts using plotKML

Milan Kilibarda kili at grf.bg.ac.rs
Sat Dec 22 16:31:27 CET 2012


Dear Paul,
Maybe you can solve you problem in this way.

I agree with ---Barry--yes its too bad about the pie charts--this is how the data has been
presented in the past, so we do what me must!

# plotGoogleMaps solution to plot 3 variables in piecharts
library('plotGoogleMaps')
data(meuse)
coordinates(meuse)<-~x+y
proj4string(meuse) <- CRS('+init=epsg:28992')

m<-segmentGoogleMaps(meuse,zcol=c('zinc','lead','copper'),filename='myMap.htm')
#################################################################################

# This function can help you to find solution to your problem in plotKML


# Function creates SPolyDF from points, piecharts from points  , modified from plotGoogleMaps package
pie<-function(SPDF,
                        zcol=1:length(SP at data),
                        scalelist=TRUE,  # TRUE proportional, FALSE pie charts same size
                        max.radius=100,  #m
                        do.sqrt = TRUE,
                        colPalette=rainbow(ncol(SP at data[,zcol])),
                        fillColor=rainbow(length(key.entries)),
                        strokeColor="red"){

####  FUNCTION modified from plotGoogleMaps package

    createSphereSegment <- function(partOfSP,
                                  max.radius=100,  #m
                                 key.entries = as.numeric(partOfSP at data),
                                 scalelist=1,
                                 do.sqrt = TRUE,
                                 fillColor=rainbow(length(key.entries)),
                                 strokeColor="red",
                                 id=length(key.entries)) {

     center=coordinates(partOfSP)
    fillColor<-as.character(substr(fillColor,1,7))

    	obj = as(partOfSP, "SpatialPointsDataFrame")
    		z = as.numeric(partOfSP at data)
        	# avoid negative values
        	if (min(key.entries)<0 ){
        	ke<-abs(min(key.entries))+ key.entries+mean(key.entries)
        	}else{ke<-key.entries+min(key.entries)}     # no zeros for radius vecor
        	# creating a vector for subgroupes
        	if(do.sqrt){
        	scale.level<- sqrt(ke/(max(ke)) ) }else{scale.level<-ke/(max(ke))}
    	radius.level<-max.radius*scale.level
    	 # list of radiuses for createSphereCircle
    	radius.vector<-   radius.level
    	dfi<-cbind(rep(NA,1+length(radius.vector)))
    	dfi[1]=0

    	if(max(scale.level)==0)
                              {scale.level=0.1
                               scalelist=0.01}

    	dfi[2:(length(radius.vector)+1)]=360/sum(scale.level)*  scale.level


    	fi= cbind(rep(NA,2*length(radius.vector)) )
    	dfi=as.numeric(dfi)
     for (i in (seq(2,length(fi),by=2))){
     fi[i]=sum(dfi[1:(i/2+1)])
     }
     fi[1]=0
       for (i in (seq(3,length(fi),by=2))){
     fi[i]=fi[i-1]
     }


    radius.vector=scalelist*max.radius/6378000
    # radius<-	spDistsN1(pts=rbind(c(soil.ll at bbox[1,1],soil.ll at bbox[2,1])),
pt=c(soil.ll at bbox[1,2],soil.ll at bbox[2,2]), longlat = T)/6378	## radians

    		lat1 <- (pi/180)* center[2];
    	  lng1 <- (pi/180)* center[1];

      paths<-as.list(rep(NA,length(radius.vector)))

     for(ik in (seq(2,length(fi),by=2))){
         radius<-  radius.vector

        coords<-cbind(rep(NA,11),rep(NA,11))
        coords[1,]  <- c(  center[,1], center[,2])
          j<-2
    		for (i in seq(fi[ik-1],fi[ik],length.out=10)) {
    			tc <- (pi/180)*i
    			y <- asin(sin(lat1)*cos(radius)+cos(lat1)*sin(radius)*cos(tc))
    			dlng <- atan2(sin(tc)*sin(radius)*cos(lat1),cos(radius)-sin(lat1)*sin(y))
    			x <- ((lng1-dlng+pi) %% (2*pi)) - pi

    			coords[j,1] <-c(x*(180/pi))
    			coords[j,2] <-c(y*(180/pi))
    			j<-j+1
    		}



           lonlat<-coords
           paths[[ik/2]]<-rbind(lonlat,lonlat[1,])
                     }
     pol=paths
     lonlat<-rbind( paths[[1]],paths[[1]][1,])
     pol[[1]]<-Polygon(lonlat,hole=FALSE)
     pol[[1]]<-Polygons(list(pol[[1]]),ID=id-1)

         for(i in (2:(length(paths)))){
              lonlat<-rbind( paths[[i]],paths[[i]][1,])
               pol[[i]]<-Polygon(lonlat,hole=FALSE)
               pol[[i]]<-Polygons(list(pol[[i]]),ID=id-i)   }


      # Vrace Polygons obj koji je lista Polygon objekata
      return(pol)

                     }

###########################################################################
#####            END
##########################################################################

SP <-as(SPDF, "SpatialPointsDataFrame")
SP.ll <- spTransform(SP, CRS("+proj=longlat +datum=WGS84"))
SP.ll<-SP.ll[,zcol]

if(strokeColor!=""){
    rgbc<-col2rgb(strokeColor)
    strokeColor<-rgb(rgbc[1],rgbc[2],rgbc[3],maxColorValue=255) }

    if(!is.null(colPalette)){
    rgbc<-col2rgb(colPalette)
    colPalette<-apply(rgbc,2,function(x) rgb(x[1],x[2],x[3],maxColorValue=255))}
  if(scalelist){
    xdata<-SP at data[,zcol]
    xdata <- apply(xdata, 2L, function(x) (x - min(x, na.rm = TRUE))/diff(range(x, na.rm = TRUE)))
    xsum <- apply(xdata, 1L,function(x) ( sum(x)))
    scalelist<-xsum/max(xsum)
    scalelist<-sqrt(scalelist)} else{ scalelist<-rep(1,length(SP.ll at coords[,1])) }

  Pols<-as.list(rep(NA,length(SP.ll[,1])))
  Srl<-Pols
   num=(rep(NA,length(zcol)*length(SP.ll at data[,1])) )
  for(i in 1:length(SP.ll at data[,1])){
    Pols[[i]]<-createSphereSegment(SP.ll[i,zcol],
                              max.radius=max.radius,  #m
                             key.entries = as.numeric(SP.ll at data[i,zcol]),
                             scalelist= scalelist[i],
                             do.sqrt = do.sqrt,
                             fillColor=colPalette,
                             strokeColor= strokeColor,
                             id=i*length(key.entries))
                             num[i*length(zcol)-(0:(length(zcol)-1))]=i

                                      }

   id=num  # rep(1:length(zcol),length(SP.ll at data[,1]))
  dat=data.frame(id)
  SP$id=1: length(SP.ll at data[,1])
  dat=merge(dat,SP at data)
  Pols=unlist(Pols)
  SPl<-SpatialPolygons(Pols,proj4string=SP.ll at proj4string)
  SPldf<-SpatialPolygonsDataFrame(SPl,dat,match.ID = FALSE)
  return(SPldf)
}

###########################  END OF FUNCTION pie ###############################

 a=pie(meuse,zcol=c('zinc','lead','copper'))
 spplot(a)
 a$col=rep(c('zinc','lead','copper'),155)
 m=plotGoogleMaps(a,zcol='col',colPalette=c('red','green','blue') )

 # Similary you can try it to plot in plotKML , I don't have package at home

Best,
Milan


> On Fri, Dec 21, 2012 at 3:53 PM, Paul Galpern <pgalpern at gmail.com> wrote:
>> Dear list,
>>
>>    This question pertains to the very nice package, plotKML.
>>
>>    Does anyone know of an efficient way to render pie charts on Google
>> Earth using plotKML? Creating thousands of little pie images and using
>> the SpatialPhotoOverlay class doesn't seem viable.
>>
>>    The only other thing I can think of is rendering each segment of each
>> pie (of which there may be thousands) as a SpatialPolygons object.  But
>> this, again, seems like a lot of work (and likely to produce a very
>> large KML file).
>
> These guys:
>
> http://blog.thematicmapping.org/2008/04/using-google-charts-with-kml.html
>
> call the google charts API to generate the pie charts. Sneaky. You
> don't have to include the images in the KML, they get generated by the
> API on the fly (I think).
>
>  Anyway, pie charts are bad, mmmkay?
>
> Barry
>
> _______________________________________________
> R-sig-Geo mailing list
> R-sig-Geo at r-project.org
> https://stat.ethz.ch/mailman/listinfo/r-sig-geo
>


Milan Kilibarda

University of Belgrade,
Faculty of Civil Engineering,
Department of Geodesy and Geoinformatics,
Address: Bulevar kralja Aleksandra 73
   11000 Belgrade, Serbia,
Mail:  kili at grf.bg.ac.rs

tel:+381 11 3218516



More information about the R-sig-Geo mailing list