R & GGPLOT – Expanded Plots


Learn how to create expanded inserts like this easily in R with this ggplot template.

Learn how to create expanded inserts like this easily in R with this ggplot template.

>>GET THE R CODE<<

R and GGPLOT are great! There are some things, however, that I want to be able to do easily. For these things I have to create template codes, which I want to share with you!

This time around I wanted to show you how you can create “zoomed” areas of a plot and insert them into your main plot. This template will also show you how you can insert a completely different plot as an insert. This could be a table, map,….anything. This is a common thing to see in many plots, and alas now the functionality can be achieved easily.

DOWNLOAD TEMPLATE – Link to download from my script archive

Summary of the code:

  • You will define two plots: p1 and p2
    • p1 is the main plot – code it normally
    • p2 is the zoomed in area of p1 – the code for this is almost the same (see differences below)
    • p2 is placed inside of p1 and placed automatically into one of the corners that you specify
  • The differences between p1 and p2 are:
    • p1 has a rectangular grob defining the zoomed area – make sure the variables for its limits are linked to the customisation variables!
    • p2 has had the theme options changed to get rid of scales etc – we basically want the plot area to take up the entire device for p2, with no scales or padding.
  • Most of the customisation in the template is automated with variables – found at the top of the document
    • zoom – set the level of zoom
    • pad – set the padding of the insert
    • ex.col – fill colour of the expand boxes if you wish
    • ex.alpha – set this alpha to zero if you don’t want a fill
    • ex.lin – line colour of the zoom boxes
    • x.expand – the x range you wish to expand
    • y.expand – the y range you wish to expand
    • j.expand – the corner you wish the zoomed box to be in
    • ….other variables must be defined, but these are nicely laid out in a box at the top of the code
  • Awesome features of the code include
    • Aspect ratio is maintained for your zoomed area
    • Level of zoom can be easily defined – everything else is adjusted accordingly
    • The zoomed area is labeled with a zoom level
    • You can position the expanded box in any corner simply by defining j.expand as “tl” for Top Left etc – the computation of plotting coordinates is done automatically
    • Resolution is dynamic in the zoom box – so if you change your mind about zoom, it can be adjusted at 100% resolution – no loss

DOWNLOAD TEMPLATE – Link to download from my script archive

The code is easily customised, but pay attention to areas of code that are linked into customisation parameters. When you create your own code you should link in these variables into your plot to allow easy editing! To help you out with this, parts of the plot code that contain variables linked into the customisation parameters are commented with “#IMPORTANT“. As a general rule, though, follow this workflow:

  1. Create your base plot (p1)
  2. Define the rectangular grob (using customisation variables)
  3. Copy and use theme () options from p1 in the template
  4. Duplicate p1 to create p2
  5. Copy and use the theme () options for p2 from the template

If you have any questions, please don’t hesitate to comment. If you are having problems, provide simple examples of code which exhibit the problem you’re having and I’ll do my best to look at it!

Below are some edits of the code that show you how easily things can be changed…

zoom = 2.6

zoom = 2.6

pad = 3Screen Shot 2013-11-26 at 19.26.38

ex.lin = “red”

Screen Shot 2013-11-26 at 19.28.04

zoom = 5; pad = 1; x.expand = c(3, 4); y.expand = c(13, 16), j.expand = “br”

Screen Shot 2013-11-26 at 19.33.19

#21 – Find significant relationships in data with a CoCo Matrix


Screen Shot 2013-08-19 at 08.47.17

The CoCo Matrix (correlation coefficient matrix) is a script for R that takes a table headed with multiple variables and calculates the correlation coefficients between each of the variables, determines which are statistically significant, and represents them visually in a grid-plot. I created the CoCo Matrix to cross correlate a table with a large number of variables to quickly assess where important correlations could be found.

Screen Shot 2013-08-19 at 08.47.27

Using the CoCo Matrix

The R file can be downloaded here or copied from the textbox at the end of this post.

  1. If you know the number of samples in your dataset (n) then degrees of freedom (df) = n-2. Use this table to find the R value above which significant values lie. In the code, at the top you should change the value of “p” as per the value you just looked up. If you don’t know the value for n then run the code once and type “n” into the console.
  2. If you want, customise the colours in the customisation area of the code
  3. Run the code. A dialogue box will request a file. Alternatively replace the code to direct to the file you want to use.
  4. Voila!

This is a very rough script I wrote, and I intend to make it a lot better at some point when I have the time. If you have any suggestions  for improvements then please comment below or get in touch with me.

# CoCo Matrix version 1.0
# Written by Darren J. Wilkinson
# wilkinsondarren.wordpress.com
# d.j.wilkinson@ed.ac.uk
#
# The "CoCo Matrix" visualises the correlation coefficients for a given set of data.
# Like-Like correlations are given NA values (e.g. Height vs Height = NA). For the moment
# duplicates such as Height vs. Weight and Weight vs. Height remain. At some point I'll 
# provide an update that removes duplicates like that.
#
# Please feel free to edit the code, and if you make any improvements please let me know
# either on wilkinsondarren.wordpress.com or send me an email at d.j.wilkinson@ed.ac.uk

# Packages -------
library (cwhmisc)
library (ggplot2)
library (grid)
library (scales)
# ----------------

# Plot Customisation ----------------------------------------------------------
# (for good colour suggestions visit colourlovers.com)
col.significant = "#556270"			# Colour used for significant correlations
col.notsignificant = "lightgrey"		# Colour used for non-significant correlations
col.na = "white"						# Colour used for NA values
e1 = c("nb", "ta", "ba", "rb", "hf", "zr", "yb", "y", "th", "u")   #  p) {s = "Significant"}
		if (temp < p) {s = "Not Significant"}
		if (temp == 1) {s = NA}
		if (temp == 1) {temp = NA}
		results[h,i] = temp
		plot.data[r,4] = s
		plot.data[r,3] = temp
		plot.data[r,2] = h
		plot.data[r,1] = i
	}

}

# Open new quartz window
dev.new (
	width = 12, 
	height = 9
	)

# Plot the matrix
ggplot (data = plot.data, aes (x = x, y = y)) + 

geom_point (aes (colour = sig), size = 20) + 

scale_x_continuous (labels = e1, name = "", breaks = c(1:n.e1)) +

scale_y_continuous (labels = e1, name = "", breaks = c(1:n.e1)) +

scale_colour_manual (values = c(col.notsignificant, col.significant, col.na)) +

labs (title = "CoCo Matrix v1.0")+

theme (
	plot.title = element_text (vjust = 3, size = 20, colour = "black"), #plot title
	plot.margin = unit (c(3, 3, 3, 3), "lines"), #adjust the margins of the entire plot
	plot.background = element_rect (fill = "white", colour = "black"),
	panel.border = element_rect (colour = "black", fill = F, size = 1), #change the colour of the axes to black
	panel.grid.major = element_blank (), # remove major grid
	panel.grid.minor = element_blank (),  # remove minor grid
	panel.background = element_rect (fill = "white"), #makes the background transparent (white) NEEDED FOR INSIDE TICKS
	legend.background = element_rect (colour = "black", size = 0.5, fill = "white"),
	legend.justification = c(0, 0),
	#legend.position = c(0, 0), # put the legend INSIDE the plot area
	legend.key = element_blank (), # switch off the rectangle around symbols in the legend
	legend.box.just = "bottom",
	legend.box = "horizontal",
	legend.title = element_blank (), # switch off the legend title
	legend.text = element_text (size = 15, colour = "black"), #sets the attributes of the legend text#
	axis.title.x = element_text (vjust = -2, size = 20, colour = "black"), #change the axis title
	axis.title.y = element_text (vjust = -0.1, angle = 90, size = 20, colour = "black"), #change the axis title
	axis.text.x = element_text (size = 17, vjust = -0.25, colour = "black"), #change the axis label font attributes
	axis.text.y = element_text (size = 17, hjust = 1, colour = "black"), #change the axis label font attributes#
	axis.ticks = element_line (colour = "black", size = 0.5), #sets the thickness and colour of axis ticks
	axis.ticks.length = unit(-0.25 , "cm"), #setting a negative length plots inside, but background must be FALSE colour
	axis.ticks.margin = unit(0.5, "cm") # the margin between the ticks and the text
	)

# Print data tables in the console
results
plot.data

#15 Alkali Silica Template


Alkali Silica

Does what it says on the tin.

DOWNLOAD THE CODE

#------------------------------
#-------- INFORMATION ---------
#------------------------------
# Plotting points from Hugh
# Rallinson's "Using Geochemical
# Data" book. Code compiled by
# Darren J. Wilkinson,
# Grant Inst. Earth Science
# The University of Edinburgh
# d.j.wilkinson@ed.ac.uk
#------------------------------

# -------- CONTROLS ----------
y.max = 16
x.min = 35
x.max = 80
lab.size = 5
save = "/Users/s0679701/Desktop/"
filename = "test.png"
#------------------------------

# -------- LIBRARIES ----------
library (grid)
library (scales)
library (ggplot2)
#------------------------------

# -------- DON'T EDIT ----------
a = c(1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 8, 8)
x = c(41.0,41.0,52.5,50.0,52.5,57.6,63.0,63.0,45.0,45.0,61.0,63.5,45.0,52.0,57.0,63.0,69.0,45.0,49.4,52.0,52.0, 48.4,53.0,57.0,57.0,69.0,69.0,76.6,41.0,45.0)
y = c(0.500,7.000,14.000,15.126,14.000,11.700,7.000,0.500,0.500,5.000,13.500,14.830,5.000,5.000,5.900, 7.000,8.000,9.400,7.300,5.000,0.500,11.500,9.300,5.900,0.500,12.500,8.000,0.500,3.000,3.000)
lines = data.frame (a, x, y)

b = c("Picro-Basalt", "Basalt", "Basaltic Andesite", "Andesite", "Dacite", "Basanite", "Trachy Basalt", "Basaltic Trachyandesite", "Trachyandesite", "Trachydacite", "Rhyolite", "Tephrite", "Phonotephrite", "Tephriphonolite", "Trachyte", "Foidite", "Phonolite")
c = c(1:17)
x = c(43, 48.5, 54.5, 60, 68, 43, 48.75, 53, 57.5, 65, 75, 46, 49, 53, 65, 45, 58)
y = c(2, 2.5, 3, 3.5, 4, 6, 5.5, 6.5, 8.5, 9, 8, 8, 9.5, 11.5, 12, 13, 14)
labels = data.frame (b, x, y)

x = c(39.8,65.5) #MacDonald (1968)
y = c(0.35, 9.7) #MacDonald (1968)
sub = data.frame (x, y)
#------------------------------

# -------- BEGIN PLOT ----------

ggplot (lines, aes (x=x, y=y)) +

# Field Boundaries
geom_line (
aes(linewidth = factor (a))
) +

# Alkaline-Tholeiitic Line
geom_line (
data = sub,
aes (x=x, y=y),
linetype = "longdash"
) +

# Field Labels
geom_text (
data = labels,
aes(x = x, y = y, label = b),
size = lab.size
) +

scale_x_continuous (
name = (expression(paste("SiO"["2"], " (wt. %)"))),
limits = c(x.min, x.max)
) +

scale_y_continuous (
name = (expression(paste("Na"["2"], "O + K"["2"], "O", " (wt. %)"))),
breaks = c(seq(0, y.max, 2)),
limits = c(0, y.max)
) +

theme (
plot.title = element_text (vjust = 3, size = 20), #plot title
plot.margin = unit (c(3, 3, 3, 3), "lines"), #adjust the margins of the entire plot
panel.border = element_rect (colour = "black", fill = F, size = 2), #change the colour of the axes to black
panel.grid.major = element_blank (), # remove major grid
panel.grid.minor = element_blank (), # remove minor grid
panel.background = element_rect (fill = "white"), #makes the background transparent (white) NEEDED FOR INSIDE TICKS
legend.background = element_rect (fill = "white"),
legend.justification=c(1, 1),
legend.position = c(1, 1), # put the legend INSIDE the plot area
legend.key = element_blank (), # switch off the rectangle around symbols in the legend
legend.title = element_blank (), # switch off the legend title
legend.text = element_text (size = 15), #sets the attributes of the legend text
axis.title.x = element_text (vjust = -2, size = 20), #change the axis title
axis.title.y = element_text (vjust = -0.1, angle = 90, size = 20), #change the axis title
axis.text.x = element_text (size = 17, vjust = -0.25, colour = "black"), #change the axis label font attributes
axis.text.y = element_text (size = 17, hjust = 1, colour = "black"), #change the axis label font attributes
axis.ticks = element_line (colour = "black", size = 0.5), #sets the thickness and colour of axis ticks
axis.ticks.length = unit(-0.25 , "cm"), #setting a negative length plots inside, but background must be FALSE colour
axis.ticks.margin = unit(0.5, "cm") # the margin between the ticks and the text
)

ggsave (paste (save, filename), height = 12, width = 18, dpi = 75)

#14 A New GGPLOT Template


Screen Shot 2013-02-13 at 10.46.11

 

So the opts() has now been given the boot, and all the cool kids are using theme() to customise their ggplots. If you’re still on an old version of R then theme() will still work, but if you update (which you should) then it’ll stop working and you’ll have to edit all your code which uses theme ().

Here is my standard template giving you a style for simple, publication friendly ggplot plots.

# Load Packages
library (ggplot2) # Needed for plotting
library (grid) # Needed for customising plot area
library (scales) # Needed for ediring log tickmarks

# Select Font Size
size1 = 20 # Plot and Axis Titles
size2 = 17 # Legend Title
size3 = 15 # Axis Labels

ggplot (
     data = mtcars,
     aes (
     x= disp,
     y= drat
     )
     ) +

geom_point (
     aes(
     colour = mpg
     ),
     size = 5
     ) +

scale_y_log10 (
     limits = c(0.01, 10),
     name = "Axis Title Here",
     label = trans_format('log10',math_format(10^.x)) # Format = 10^x rather than 1e10x (also use label = comma)
     ) +

scale_x_log10 (
      limits = c(10, 1000),
     name = "Axis Title Here",
     label = trans_format('log10',math_format(10^.x)) # Format = 10^x rather than 1e10x (also use label = comma)
     ) +

annotation_logticks ( # Turn on minor ticks
     short = unit (0.2, "cm"), # Minor tick length
     mid = unit (0.2, "cm"), # ...
     long = unit (0.2, "cm"), # ...
     side = "lbrt") + # l = left, b = bottom etc

labs ( # New way of setting some attributes.
     colour = "MPG",
     title = "Plot Title"
     ) +

theme (
      plot.title = element_text (vjust = 3, size = 20), # plot title attrib.
      plot.margin = unit (c(3, 3, 3, 3), "lines"), # plot margins
      panel.border = element_rect (colour = "black", fill = F, size = 1), # axis colour = black
      panel.grid.major = element_blank (), # remove major grid
      panel.grid.minor = element_blank (), # remove minor grid
      panel.background = element_rect (fill = "white"), # background colour
      legend.background = element_rect (fill = "white"), # background colour
      legend.justification=c(0, 0), # lock point for legend
      legend.position = c(0, 0), # put the legend INSIDE the plot area
      legend.key = element_blank (), # switch off the rectangle around symbols in the legend
      legend.title = element_blank (), # switch off the legend title
      legend.text = element_text (size = 15), # sets the attributes of the legend text
      axis.title.x = element_text (vjust = -2, size = 20), # change the axis title
      axis.title.y = element_text (vjust = -0.1, angle = 90, size = 20), # change the axis title
      axis.text.x = element_text (size = 17, vjust = -0.25, colour = "black"),# change the axis label font attributes
      axis.text.y = element_text (size = 17, hjust = 1, colour = "black"), # change the axis label font attributes
      axis.ticks = element_line (colour = "black", size = 0.5), # sets the thickness and colour of axis ticks
      axis.ticks.length = unit(-0.25 , "cm"), # -ve length = inside ticks
      axis.ticks.margin = unit(0.5, "cm") # margin between the ticks and the text
      )

#13 Mapping in R: Representing geospatial data together with ggplot


homies1

I have been trawling around for a while now trying to find a simple and understandable way of representing geospatial data in R, whilst retaining the ability to manipulate the visualisation in ggplot. After much searching I came across some articles which got me to a working product only after a lot of ball ache. All the coding is done in R, so if you don’t know what it is click here. I keep the code simple, mainly because I don’t need it to be more complex for my purposes, but it also helps newbies like me learn the syntax faster.

GGMAP is a package that was developed by David Kahle and Hadley Wickham (Hadley being the guy behind ggplot2). If you want more detail see David’s slides from the 8th International R User Conference.

 
1.0 Fetching a Map

Maps may be brought into R from a number of sources, the two main ones are GoogleMaps and OpenStreetMap. The code needed to fetch the map is slightly different depending on where you want the data from. Below are some examples:

 
libary (ggmap) 

ggmap(
	get_googlemap(
		center=c(-3.17486, 55.92284), #Long/lat of centre, or "Edinburgh"
		zoom=14, 
		maptype='satellite', #also hybrid/terrain/roadmap
		scale = 2), #resolution scaling, 1 (low) or 2 (high)
		size = c(600, 600), #size of the image to grab
		extent='device', #can also be "normal" etc
		darken = 0) #you can dim the map when plotting on top

ggsave ("/Users/s0679701/Desktop/map.png", dpi = 200) #this saves the output to a file

This outputs the following files:

maptype = "satellite"

maptype = “satellite”

maptype = "roadmap"

maptype = “roadmap”

maptype = "terrain"

maptype = “terrain”

We can also obtain a map from OpenStreetMap:

libary (ggmap) 

ggmap(
	get_openstreetmap (
	bbox = c(-3.16518, 55.91899, -3.18473, 55.92716), 
	format = "png"
	),

ggsave ("/Users/s0679701/Desktop/map.png", dpi = 200) #this saves the output to a file

You may receive the following error:

 Error: map grabbing failed - see details in ?get_openstreetmap.
In addition: Warning message:
In download.file(url, destfile = destfile, quiet = !messaging, mode = "wb") :
  cannot open: HTTP status was '503 Service Unavailable'

This is because the OpenMapServer has issues, and so you just need to be lucky! Hence why there is no OpenStreetMap for this example…. yet.

 
2.0 Plotting on a Map

You can plot any [x,y, +/- z] information you’d like on top of a ggmap, so long as x and y correspond to longitudes and latitudes within the bounds of the map you have fetched. To plot on top of the map you must first make your map a variable and add a geom layer to it. Here is an example:

libary (ggmap) 

#Generate some data
long = c(-3.17904, -3.17765, -3.17486, -3.17183)
lat = c(55.92432, 55.92353, 55.92284, 55.92174)
who = c("Darren", "Rachel", "Johannes", "Romesh")
data = data.frame (long, lat, who)

map = ggmap(
	get_googlemap(
		center=c(-3.17486, 55.92284), 
		zoom=16, 
		maptype='hybrid', 
		scale = 2), 

		size = c(600, 600),
		extent='normal', 
		darken = 0)

map + geom_point (
		data = data,
		aes (
			x = long, 
			y = lat, 
			fill = factor (who)
			), 
		pch = 21, 
		colour = "white", 
		size = 6
		) +

	scale_fill_brewer (palette = "Set1", name = "Homies") +

	#for more info on these type ?theme()	
	theme ( 
		legend.position = c(0.05, 0.05), # put the legend INSIDE the plot area
		legend.justification = c(0, 0),
		legend.background = element_rect(colour = F, fill = "white"),
		legend.key = element_rect (fill = F, colour = F),
		panel.grid.major = element_blank (), # remove major grid
		panel.grid.minor = element_blank (),  # remove minor grid
		axis.text = element_blank (), 
		axis.title = element_blank (),
		axis.ticks = element_blank ()
		) 

ggsave ("/Users/s0679701/Desktop/map.png", dpi = 200)

homies1homies2

This simple code should be enough to get you going making your own plots. If you have any questions about this code or your own, then please don’t hesitate with getting in touch via the comments below.

Happy Mapping!

#4 R: A powerful tool for the geochemist


The graph shows contoured fields generated from data scatters, overlain by scattered points. Contours are based on a density distribution estimated by the ggplot2 package, the data is simply xy.

 

R is an incredibly powerful programming tool used by a large community of people who require an easy to use, light weight, FREE, and fundamentally awesome statistics package! I have recently discovered that R can be used by geologists whose IT skills are often pitied by their more computer literate geophysicist colleagues. Long story short – if you are using excel on large data sets then you will more than likely find that using R is a much better solution for analysing and graphing your geochemical data.

Here are some useful links to get you started:

I’m still learning R myself, but when I come across useful things I very much intend to share them. This includes useful code for fellow igneous/metamorphic geochemists!