Here is a pretty simple function. -tgs ColorBlocks <- function(rows, columns, ColorMatrix, RowNames, ColumnNames, TextMatrix = NULL){
# This function takes the following inputs: # rows : a numeric vector denoting the relative heights of rows # columns : a numeric vector denoting the relative widths of columns # ColorMatrix : a numeric matrix of integers representing colors # RowNames : a character vector of row names # ColumnNames : a character vector of column names # TextMatrix : optional, a character matrix of text to print in the center of each rectangle # Colors are selected from palette(). To change colors, see help(palette). rows <- rows / sum(rows) columns <- columns / sum(columns) old.pars <- par(no.readonly=TRUE) LeftMargin <- max(strwidth(RowNames,"inches")) * 1.04 TopMargin <- max(strheight(ColumnNames,"inches")) * 1.4 par(tcl = 0, mgp = c(1,.2,0),mai=c(0.04,LeftMargin,TopMargin,0.04),cex.axis=.8) plot.new() plot.window(xlim=c(0,1),ylim=c(-1,0),xaxs='i',yaxs='i') rrr <- -c(0,cumsum(rows)) ccc <- c(0,cumsum(columns)) for(i in 1:nrow(ColorMatrix)){ for(j in 1:ncol(ColorMatrix)){ rect(ccc[j],rrr[i+1],ccc[j+1],rrr[i],col=ColorMatrix[i,j],border="white") if(!is.null(TextMatrix[i,j])) text( mean(ccc[j:(j+1)]), mean(rrr[i:(i+1)]), TextMatrix[i,j]) } } axis(2,at = -(cumsum(rows) + head(-rrr,-1))/2, labels = RowNames,line=0,las=1) axis(3,at = (cumsum(columns) + head(ccc,-1))/2, labels = ColumnNames) box() par(old.pars) } Z <- textConnection(" country TWh Australia 244 Canada 522 China 3503 EU 2500 India 689.5 Japan 997 USA 3960 ") CountryEnergy <- read.table(Z,header=TRUE) close(Z) Z <- textConnection(" Product TWh Freezer 72.4 Refrigerator 379 HVAC 466 Lighting 123 Television 152 ") ProductEnergy <- read.table(Z,header=TRUE) close(Z) #Generate Random Color Matrix set.seed(325034) RandomColors <- matrix(sample(1:100,35),nrow=7,ncol=5) #Choose the entire palette of colors palette(colors()) # ColorBlocks( rows = CountryEnergy[,2], columns = ProductEnergy[,2], ColorMatrix = RandomColors, RowNames = CountryEnergy[,1], ColumnNames = ProductEnergy[,1] ) On Fri, Dec 14, 2012 at 4:12 PM, Neal Humphrey <nhumph...@clasponline.org>wrote: > Your right, the way Ive proposed the graphic it simplifies the story. In > this graph, the size of the box is approximately how much energy that > country uses for that appliance but not exactly. For most appliances it > should be an okay estimate, although for example air conditioners in Russia > would be an exception. **** > > ** ** > > Im proposing this format mostly for readability when there are 20-30 > countries and appliances, Im concerned about misaligning the appliances > from their labels. The main story Im trying to tell with the graphic is > how much standards coverage there is and for which appliances, while the > amount of energy is a secondary variable. Its also secondary because the > actual energy savings potential from a standard will vary widely based on > how strict the standard is. **** > > ** ** > > I was planning to complement this with a treemap > graphic<http://flowingdata.com/2010/02/11/an-easy-way-to-make-a-treemap/>, > where you trade off readability of the secondary category for accurate > representation of per country per appliance energy use. **** > > ** ** > > Talking through it now, maybe youre right that just going with the > Marimekko-like plot, with some careful formatting cleanup in Illustrator, > is a better representation? Id need to make some assumptions to fill holes > in my data (its hard to get per country-per appliance data at the level of > granularity Im aiming for). **** > > ** ** > > Im open to critiques or suggestions about the approach. Either way, I > still need to figure out how to do the true/false color coding so any > pointers on that are welcome. **** > > ** ** > > ** ** > > ** ** > > *Neal Humphrey* > > Tel: +1 202.662.7241 | Skype: neal.s.humphrey | nhumph...@clasponline.org* > *** > > www.clasponline.org**** > > ** ** > > ** ** > > *From:* tgstew...@gmail.com [mailto:tgstew...@gmail.com] *On Behalf Of *Thomas > Stewart > *Sent:* Friday, December 14, 2012 3:18 PM > *To:* Neal Humphrey > > *Subject:* Re: [R] Combined Marimekko/heatmap**** > > ** ** > > Neal-**** > > ** ** > > Help me understand something: In my mind, the size of each box---say > Country A, appliance A1---should communicate the percentage of (total) > energy consumption in country A using appliance A1. They way you've set up > your plot does not do that. I guess my question is: What information does > the size of the box communicate in your plot?**** > > ** ** > > I'd be happy to help once I understand.**** > > ** ** > > -tgs**** > > ** ** > > On Fri, Dec 14, 2012 at 1:03 PM, Neal Humphrey <nhumph...@clasponline.org> > wrote:**** > > Thomas, > > This is a big help for getting me started. Brand new to R, so I'm > unfamiliar with how to 'manually' drawing graphs (instead of packages). > > The graph your code makes is more like a Marimekko chart. What I'm > thinking of is like a heatmap but each row has a different width, and each > column has a different width. But, for any particular column, the width is > the same all the way down. > > I used your code to figure out how to draw lines on a chart the way I need > this to look. Now what I need to figure out is how to add color coding to > the respective squares. In my example it's binary data (yes/no), but a more > robust approach would allow for a true heatmap. > > Any help on getting this to the next step of color coding would be much > appreciated! The code below will draw a grid that is scaled per the sample > data on the x and y axes. Perhaps what is needed is to draw boxes rather > than lines to make the grid? I'm not sure. > > Neal**** > > > par(mar=c(1,1,1,1), > oma = c(0,0,0,0), > mgp=c(1.5,.2,0), > tcl=0, > cex.axis=.75, > col.axis="black", > pch=16)**** > > #--------Input the sample data------------------- > Z <- textConnection(" > country TWh > Australia 244 > Canada 522 > China 3503 > EU 2500 > India 689.5 > Japan 997 > USA 3960 > ") > CountryEnergy <- read.table(Z,header=TRUE) > close(Z) > > Z <- textConnection(" > Product TWh > Freezer 72.4 > Refrigerator 379 > HVAC 466 > Lighting 123 > Television 152 > ") > ProductEnergy <- read.table(Z,header=TRUE) > close(Z) > > #-------------Binary data indicating whether that country/product > combination has a standard---------------- > #-------------Rows correspond to countries (in the same order as the > CountryEnergy matrix)------------------ > #-------------Columns correspond to products (in the same order as the > ProductEnergy matrix)---------------- > Z <- textConnection(" > country TWh > 0 1 0 0 1 > 0 1 1 1 0 > 1 0 1 0 0 > 1 1 1 0 0 > 0 1 1 1 1 > 1 0 0 0 1 > 1 0 0 0 0 > ") > ddd <- read.table(Z,header=FALSE) > close(Z) > > #-----------rewrite the data table so that the vector is numbers only, and > label the rows---------- > row.names(CountryEnergy) <- CountryEnergy$Country > CountryEnergy<-CountryEnergy[,2:2] > row.names(ProductEnergy) <- ProductEnergy$Product > ProductEnergy <- ProductEnergy[,2:2] > > > #-----------plot the grid------------ > plot.new() > plot.window(ylim=c(0,sum(CountryEnergy)),xlim=c(0,sum(ProductEnergy)),xaxs > = 'i',yaxs='i',las=1) > box() > abline(h = cumsum(CountryEnergy),lwd=2, col="gray60") #lwd - line width > abline(v = cumsum(ProductEnergy), lwd=2, col="gray60") > > labxats <- NULL > > #----------Use ddd data to code the cells as yes/no for having a > standard--------------------- > # > # > # this is the part I need help with > # > # > # > > #---------------------------------------------------------------------------------------------- > > > Neal Humphrey > nhumph...@clasponline.org > > From: Thomas Stewart [mailto:t...@live.unc.edu] > Sent: Friday, December 14, 2012 10:36 AM > To: Neal Humphrey > Cc: r-help@r-project.org > Subject: Re: [R] Combined Marimekko/heatmap**** > > > Neal- > > Perhaps the following code is a start for what you want. > > -tgs > > par(mar=c(1,1,1,1), > oma = c(0,0,0,0), > mgp=c(1.5,.2,0), > tcl=0, > cex.axis=.75, > col.axis="black", > pch=16) > > Z <- textConnection(" > country A1 A2 A3 > A 3 4 5 > B 6 9 8 > C 6 9 5") > ddd <- read.table(Z,header=TRUE) > close(Z) > > > CountryPcts <- rowSums(ddd[,-1]) / sum(ddd[,-1]) > > plot.new() > plot.window(ylim=c(0,1),xlim=c(0,1),xaxs = 'i',yaxs='i',las=1) > box() > abline(h = cumsum(CountryPcts),lwd=2) > > labxats <- NULL > vlines <- ddd[,-1] / sum(ddd[,-1]) / CountryPcts > vlines <- t(apply(vlines,1,cumsum)) > yyy <- c(0,rep(cumsum(CountryPcts),each=2)) > yyy <- head(yyy,-1) > for(i in 1:nrow(ddd) ){ > xxx <- rep(vlines[,i],each=2) > lines(xxx,yyy,col="red",lwd=3) > labxats[i] <- rev(xxx)[1] > } > > labxats <- (labxats + c(0,head(labxats,-1)))/2 > labyats <- (cumsum(CountryPcts) + c(0,head(cumsum(CountryPcts),-1)))/2 > axis(2,at=labyats,labels = ddd[,1],las=1 ) > axis(3,at=labxats,labels = colnames(ddd)[-1],las=1 ) > > On Thu, Dec 13, 2012 at 6:09 PM, Neal Humphrey <nhumph...@clasponline.org> > wrote: > Hi all, > > I'm trying to figure out a way to create a data graphic that I haven't > ever seen an example of before, but hopefully there's an R package out > there for it. The idea is to essentially create a heatmap, but to allow > each column and/or row to be a different width, rather than having uniform > column and row height. This is sort of like a Marimekko chart in > appearance, except that rather than use a single color to represent the > category, the color represents a value and all the y-axis heights in each > column line up with each other. That way color represents one variable, > while the area of the cell represents another. > > In my application, my heatmap has discrete categorical data rather than > continuous. Rows are countries, columns are appliances, and I want to scale > the width and height of each column to be the fraction of global energy > consumed by the country and the fraction of energy use consumed by that > appliance type. The color coding would then indicate whether or not that > appliance is regulated in that country. > > Any ideas how to make such a chart, or even what it might be called? > > > Neal Humphrey > nhumph...@clasponline.org > > ______________________________________________ > R-help@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide > http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. > > > > **** > > ** ** > [[alternative HTML version deleted]]
______________________________________________ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.