6

I have a set of well-log data. In the industry, there are specialist software to produce typical borehole log plots. Here is a simplified one: well-log plot

The exciting things to note are:

  • they are essentially facet plots
  • Depth is the independent var, but is on the vertical axis
  • several couplets of well-logs are plotted, and
  • each log in a couplet may have different value ranges

Because this is a very traditional industry, I want to replicate closely the format of these plots with the software I have (I don't have the specialist stuff, being a student). I have used ggplot to get a little way along the path, but I don't know how to do some things. To kick things off, here are some example data and code:

log <- structure(list(Depth = c(282.0924, 282.2448, 282.3972, 282.5496, 
282.702, 282.8544, 283.0068, 283.1592, 283.3116, 283.464, 283.6164, 
283.7688, 283.9212, 284.0736, 284.226, 284.3784, 284.5308, 284.6832, 
284.8356, 284.988), FOO = c(4.0054, 4.0054, 4.0054, 4.0691, 4.0691, 
4.0691, 4.0674, 4.0247, 4.0247, 4.0247, 4.0362, 4.1059, 4.2019, 
4.2019, 4.2019, 4.0601, 4.0601, 4.0601, 4.2025, 4.387), BAR = c(192.126, 
190.2222, 188.6759, 188.6759, 188.6759, 189.7761, 189.7761, 189.7761, 
189.2443, 187.2355, 184.9368, 182.5421, 181.882, 181.344, 180.9305, 
180.9305, 180.9305, 181.5986, 182.4397, 182.8301)), .Names = c("Depth", 
"FOO", "BAR"), row.names = c(NA, 20L), class = "data.frame")

library(reshape2)
library(ggplot2)

# Melt via Depth:
melted <- melt(log, id.vars='Depth')

sp <- ggplot(melted, aes(x=value, y=Depth)) +
    theme_bw() + 
    geom_path() + 
    labs(title='') +
    scale_y_reverse() + 
    facet_grid(. ~ variable, scales='free_x')

I don't know how to:

  • combine two variables on one facet, and manage ranges successfully
  • have value ranges as per diagram above, at the top of the facet
  • plot labels as a separate facet. I have excluded the labels from the example data, as it was just confusing me.

Any help would be welcome.

a different ben
  • 3,900
  • 6
  • 35
  • 45
  • 1
    I'd approach (1)make the A-C facets AS you did and customize the strip text via `theme` and [`labeller`](http://stackoverflow.com/questions/16810046/ggplot2-facet-grid-custom-labeller-with-group-subscript-and-value), (2)plot the D pane with `geom_area` save that file and [extract the legend](http://stackoverflow.com/questions/21798364/independently-move-2-legends-ggplot2-on-a-map) far later. (3)Plot again with no legend. (4)Put it all together with `gridExtra::grid.arrnge` similar to last plot in [this blog post](http://www.r-bloggers.com/ggplot2-cheatsheet-for-visualizing-distributions/) – Tyler Rinker Feb 20 '14 at 01:16
  • 1
    Neat question. Depending upon how traditionalist your industry is, they will probably want axis ticks inside the plots, which can be hard with `ggplot2`. [This post](http://stackoverflow.com/questions/28949001/mirroring-axis-ticks-in-ggplot2/29023682#29023682) would be a good starting place. The reason is hard is that Hadley Wickham views ticks inside as bad form. See [his book](http://ggplot2.org/book/), [Tufte's](http://www.edwardtufte.com/tufte/books_vdqi), or [Cleveland's](http://www.stat.purdue.edu/~wsc/visualizing.html) for the theory. – Richard Erickson Apr 10 '15 at 13:53

1 Answers1

2

I don't know how to:

  • combine two variables on one facet, and manage ranges successfully

My answer just deals with the first part of your first bullet point.

The colsplit() function is useful for cases like these. Assuming variable names for multiple wells instruments are like FOO_1, FOO_2, BAR_1, BAR_2 for the measured variables FOO and BAR over wells instruments 1 and 2, then you could call colsplit after melting to add the appropriate structure back to your melted data frame.

#your data, note changed field names
log <- structure(list(Depth = c(282.0924, 282.2448, 282.3972, 282.5496, 
282.702, 282.8544, 283.0068, 283.1592, 283.3116, 283.464, 283.6164, 
283.7688, 283.9212, 284.0736, 284.226, 284.3784, 284.5308, 284.6832, 
284.8356, 284.988), FOO = c(4.0054, 4.0054, 4.0054, 4.0691, 4.0691, 
4.0691, 4.0674, 4.0247, 4.0247, 4.0247, 4.0362, 4.1059, 4.2019, 
4.2019, 4.2019, 4.0601, 4.0601, 4.0601, 4.2025, 4.387), BAR = c(192.126, 
190.2222, 188.6759, 188.6759, 188.6759, 189.7761, 189.7761, 189.7761, 
189.2443, 187.2355, 184.9368, 182.5421, 181.882, 181.344, 180.9305, 
180.9305, 180.9305, 181.5986, 182.4397, 182.8301)), .Names = c("Depth", 
"FOO_1", "BAR_1"), row.names = c(NA, 20L), class = "data.frame")

#adding toy data for 2nd well
log$FOO_2 <- log$FOO_1 + rnorm(20, sd=0.1)
log$BAR_2 <- log$BAR_1 + rnorm(20, sd=1)

#melting
melted <- melt(log, id.vars='Depth')

#use of colsplit
melted[, c('Var', 'Well')] <- colsplit(melted$variable, '_', c('Var', 'Well'))
melted$Well <- as.factor(melted$Well)

sp <- ggplot(melted, aes(x=value, y=Depth, color=Well)) +
    theme_bw() + 
    geom_path(aes(linetype=Well)) + 
    labs(title='') +
    scale_y_reverse() + 
    facet_grid(. ~ Var, scales='free_x')

enter image description here

Community
  • 1
  • 1
Curt F.
  • 4,690
  • 2
  • 22
  • 39
  • 1
    This seems like magic to me... I had never heard of this colsplit function. However, one thing to note is data from only one well is ever plotted in one of these. So the 'channel' marked as BAR would have data from two different downhole instruments. I'm working on other things for the time being, but will get back to this in future. Thanks! – a different ben Apr 14 '15 at 01:50
  • Thanks, I edited my answer to note that in addition to multiple wells it would apply to multiple sensors in the same well. – Curt F. Apr 14 '15 at 16:05