Archive

Posts Tagged ‘RGB’

Using R and ggplot2 to create a timeline visualization of UK government politics

creating an abstract timeline chart with R and ggplot

This was an attempt to visualise the ebb and flow of various political parties in the UK, over time.

The data was made available on the Guardian DataBlog, so I thought I’d have a go at producing a timeline image, using vertical strips of colour to show which party was in power in each year.

I’m not an expert in R, so there may well be a better way of doing this!

The steps taken were:-

  • download the OpenOffice spreadsheet from the Google Spreadsheet linked to on the Guardian DataBlog.
  • remove footer rows (copyright notices at the foot of the spreadsheet).
  • tidy up headers in row 1 – simplify these to single words like “Party”
  • save as a CSV, using the pipe (|) character as a delimiter. I put this in c:\infoviz\data.csv

First of all, we need to load the CSV file into a data frame

inp <- read.table("c:\\infoviz\\data.csv",header=T, sep="|")

This works fine, but the column ‘Party’ contains names like “Conservative”, “Labour” and “Liberal”.

How to convert this into something a bit more abstract, like a colour? The answer was to define a palette of colours…

palette <- c("blue", "red", "orange1", "rosybrown", "orange3", "red4", "blue4", "grey") 

.. and use a function to change a party name to a colour mentioned in that array…

getcol <- function(party) { 
	if ( party=="Conservative" | party=="Tory" )
         r<-1
     	else if ( party=="Labour" ) 
         r<-2
     	else if ( party=="Liberal" ) 
         r<-3
     	else if ( party=="Whig" ) 
         r<-4
	else if (party=="National Labour National Government") 
	   r<-6
	else if (party=="Conservative National Government") 
	   r<-7
     	else 
         r<-8
	return(palette[r])
}

Now, we can use the sapply function to map the values in the “party” column of the data frame into a colour..

inp$PartyCol <- sapply(inp$Party,getcol)

Now, the data frame has a column called ‘PartyCol’ which maps “Conservative” to “blue”, “Labour” to “red” and so on.

So now, ggplot…

qplot(factor(Year), title="history", data=inp, geom="bar", fill=factor(PartyCol), color=factor(PartyCol)) +scale_fill_identity(name=inp$PartyCol) +scale_colour_identity(name=inp$YearCol)

This shows a whole lot of labels and grids that I didn’t want…,

…so I added these options to give a clear, blank theme…

+ opts(panel.background = theme_rect(size = 1, colour = "lightgray"),panel.grid.major = theme_blank(),panel.grid.minor = theme_blank(),axis.line = theme_blank(),axis.text.x = theme_blank(),axis.text.y = theme_blank(),axis.title.x = theme_blank(),axis.title.y = theme_blank(), axis.ticks = theme_blank(),strip.background = theme_blank(),strip.text.y = theme_blank())

Here’s the whole source, if you’re brave enough to want to try this yourself!

library(ggplot2)
library(rgb)
palette <- c("blue", "red", "orange1", "rosybrown", "orange3", "red4", "blue4", "grey") 
getcol <- function(party) { 
	if ( party=="Conservative" | party=="Tory" )
         r<-1
     	else if ( party=="Labour" ) 
         r<-2
     	else if ( party=="Liberal" ) 
         r<-3
     	else if ( party=="Whig" ) 
         r<-4
	else if (party=="National Labour National Government") 
	   r<-6
	else if (party=="Conservative National Government") 
	   r<-7
     	else 
         r<-8
	return(palette[r])
}
inp <- read.table("c:\\infoviz\\data.csv",header=T, sep="|")
inp$PartyCol <- sapply(inp$Party,getcol)
qplot(factor(Year), title="history", data=inp, geom="bar", fill=factor(PartyCol), color=factor(PartyCol)) +scale_fill_identity(name=inp$PartyCol) +scale_colour_identity(name=inp$YearCol) + opts(panel.background = theme_rect(size = 1, colour = "lightgray"),panel.grid.major = theme_blank(),panel.grid.minor = theme_blank(),axis.line = theme_blank(),axis.text.x = theme_blank(),axis.text.y = theme_blank(),axis.title.x = theme_blank(),axis.title.y = theme_blank(), axis.ticks = theme_blank(),strip.background = theme_blank(),strip.text.y = theme_blank())

greyscale versus greyfail

September 7, 2009 Leave a comment

If you’ve ever wondered why desaturate gives disappointing greyscale results in Photoshop or the Gimp, here’s a (slightly) scientific demo of why.

The diagram below is the sRGB gamut, viewed from above. In reality the gamut a twisted blob in 3d space, but this is a ‘plan’ – you’re looking down on it, so you’re seeing every possible RGB hue at its highest luminosity level. You’re seeing the bright sunlit version, rather than the shadowy underbelly. Darker versions of the same hue are hidden behind the pixels you see. (This was generated with a C# program I wrote a while back.)

rgb-gamut

This triangle is called the Maxwell Triangle; the primary colours (R, G and B) are the vertices of the triangle, and every hue is a weighted average of those three primaries in different proportions. The secondary colours (Cyan, Magenta, Yellow) are mixtures of two of the primaries, and appear on the edges of the triangle.

Draw an imaginary line between each primary and the opposite secondary; where the 3 lines cross, you have the White Point – this is the axis (disappearing into your screen) of neutral tones between white and black.

Look what happens if you apply Grayscale to it

rgb-gamut-after-greyscale

Notice how Blue is darkest, Red is dark, and that White and Yellow are close together in brightness.

This is good; the greyscale algorithm takes into account human sensitivity to colour, and the influence of colour on tone. Pure yellow is lighter than pure Blue, as it is in real life.

Contrast this with the effect of applying Desaturate on the same gamut image.

rgb-gamut-after-desaturatio

Notice how white maps to white; as you’d expect. Now, the fully saturated hues (those lying on the boundary of the triangle) are all mid-grey.

Yellow is now the same tone as pure blue.

Greyscale takes into account the true tonal values of colours.

Desaturate is a simple average of the tonal values of each channel.

Desaturate? Don’t bother.

You can get a CC-NC-BY version of the gamut image at higher resolution on my Flickr stream here.