4

I'm using the following code to draw plots of two different data on same graph. And it is working well. But the problem is I'm manually scaling the data. Is it possible to autoscale them?

Here is my script

gales <- read.table("input", header=TRUE)
attach(gales)
par(mar=c(5,4,4,4)+0.1)
plot(year,number,type="l",lwd=2,las=1, col="red")
title(main = list("Title", cex=1.5,
                  col="red", font=3))
par(new=T)
plot(year,feb,type="l",lwd=2, las=1,axes=F,ylab="",col="blue")
axis(4,las=1)
mtext(side=4,line=2.5,"feb")

Here is my data

year    number  feb
1950    600 20
1951    1200    5
1952    900 5
1953    800 5
1954    800 5
1955    1100    20
1956    600 6
1957    900 10
1958    1200    20
1959    1200    20
1960    800 6
1961    900 6
1962    800 10
1963    1200    20
1964    900 15
1965    600 10
1966    600 10
1967    600 10
1968    600 10
1969    600 10
1970    1200    20

gales <- structure(list(
    year = 1950:1970,
    number = c(600L, 1200L, 900L, 800L, 800L, 1100L, 600L, 900L, 1200L, 1200L, 800L, 900L, 800L, 1200L, 900L, 600L, 600L, 600L, 600L, 600L, 1200L),
    feb = c(20L, 5L, 5L, 5L, 5L, 20L, 6L, 10L, 20L, 20L, 6L, 6L, 10L, 20L, 15L, 10L, 10L, 10L, 10L, 10L, 20L)),
    .Names = c("year", "number", "feb"), class = "data.frame", row.names = c(NA, -21L)
)
Marek
  • 49,472
  • 15
  • 99
  • 121
repinementer
  • 723
  • 3
  • 8
  • 11
  • 1
    Please use `dput` to provide data. It will keep all nuances of your data (as data types) and it's easier to read it, so you got answer faster. I edit your question to give you example. – Marek Apr 18 '11 at 10:08
  • Essentially identical to http://stackoverflow.com/q/5468280/602276 and http://stackoverflow.com/q/5665599/602276 – Andrie Apr 18 '11 at 10:57

2 Answers2

4

I agree with Richie Cotton that having two axes is considered bad form.

However, there is an alternative way of displaying the information that is conceptually sound. This is to scale the values between 0 and 1.

Here is an example using ggplot.

library(reshape2)
library(ggplot2)

gales <- structure(list(
  year = 1950:1970,
  number = c(600L, 1200L, 900L, 800L, 800L, 1100L, 600L, 900L, 1200L, 1200L, 800L, 900L, 800L, 1200L, 900L, 600L, 600L, 600L, 600L, 600L, 1200L),
  feb = c(20L, 5L, 5L, 5L, 5L, 20L, 6L, 10L, 20L, 20L, 6L, 6L, 10L, 20L, 15L, 10L, 10L, 10L, 10L, 10L, 20L)),
  .Names = c("year", "number", "feb"), class = "data.frame", row.names = c(NA, -21L)
)

Define a function that will scale values between [0; 1] corresponding to [min; max]

range01 <- function(x){(x-min(x))/(max(x)-min(x))}

gales$number <- range01(gales$number)
gales$feb <- range01(gales$feb)

Melt data to long format suitable for plotting in ggplot

mgales <- melt(gales, id.vars="year")

Create the plot

ggplot(mgales, aes(x=year, y=value, group=variable, colour=variable)) +
  geom_line(size=2)

enter image description here

Andrie
  • 176,377
  • 47
  • 447
  • 496
3

Having two lines with different scales on the same graph is generally considered bad form. (See, e.g., "Dual-Scaled Axes in Graphs" in the Perceptual Edge library.)

A better solution would be to have two panels, one above the other, with a common time axis. This is most easily done using ggplot2 or lattice.

A ggplot2 solution:

library(ggplot2)
gales_long <- melt(gales, id.vars = "year")

p_gales_ggplot2 <- ggplot(gales_long, aes(year, value)) +
  geom_line() +
  facet_grid(variable ~ ., scales = "free_y")
p_gales_ggplot2

And a lattice solution:

p_gales_lattice <- xyplot(
  value ~ year | variable,
  gales_long,
  type = "l",
  scales = list(y = list(relation = "free")),
  layout = c(1, 2)
)
p_gales_lattice
Richie Cotton
  • 118,240
  • 47
  • 247
  • 360