Auto scale data in R
Solution 1
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)
Solution 2
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
Related videos on Youtube
repinementer
Updated on May 29, 2022Comments
-
repinementer almost 2 years
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 about 13 yearsPlease 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.
-