Spencer Graves
2023-May-31 13:27 UTC
[R] plot level, velocity, acceleration with one x axis
On 5/30/23 10:23 AM, Eric Berger wrote:> What if you just precede these commands as follows: > > par(mfrow=c(3,1)) > plot(DAX.[, 1], log='y', ylab='DAX') > plot(DAX.[, 2], ylab='vel (%)') > plot(DAX.[, 3], ylab='accel (%)')Most of the space is consumed with two extraneous copies of the axis. We can get around that with three calls to par: op <- par(mfrow=c(3,1), mar=c(0, 4.1, 4.1, 2.1)) plot(DAX.[, 1], log='y', ylab='DAX') par(mar=c(0, 4.1, 0, 2.1)) plot(DAX.[, 2], ylab='vel (%)') par(mar=c(5.1, 4.1, 0, 2.1)) plot(DAX.[, 3], ylab='accel (%)') par(op) However, the three panels are NOT equal in size: roughly 30% vs. 44% vs. 26%. I can get closer using layout, but if I change the aspect ratio, it changes the relationship between the heights of the three panels. That's the problem I'm trying to solve. It's also why it makes sense to me to modify plot.ts to accept a vector for the log argument, with the constraint that length(lot) = either 1 or ncol(x). There may be a way to do it using gglot2 / the tidyverse, but I'm not facile with that, and my web searches have so far failed to produce anything better than modifying plot.ts.R (and then submitting such with compatible changes to plot.ts.Rd), as I suggested earlier. ??? Thanks, Spencer> > On Tue, May 30, 2023 at 5:45?PM Spencer Graves > <spencer.graves at effectivedefense.org> wrote: >> >> >> >> On 5/30/23 8:48 AM, Eric Berger wrote: >>> I am a bit confused as to what you are trying to achieve - and even >>> if I could guess it is not clear what the interpretation would be. >>>> head(DAX) >>> 1628.75 1613.63 1606.51 1621.04 1618.16 1610.61 >>> >>> Including the leading NA's, what would be the 6 leading terms of the 3 >>> series that you want to plot, >>> and what would be the Y labels that you want to appear at those levels >>> (assuming that there was a >>> Y label for each of them - just to understand the units you are talking about) >> >> >> DAX <- EuStockMarkets[, 'DAX'] >> DAX. <- cbind(DAX, diff(log(DAX)), diff(diff(log(DAX)))) >> colnames(DAX.) <- c("DAX", 'vel (%)', 'accel (%)') >> head(DAX.) >> >> >> DAX exhibits growth that is roughly exponential, so I want to plot it >> on a log scale: >> >> >> plot(DAX.[, 1], log='y', ylab='DAX') >> plot(DAX.[, 2], ylab='vel (%)') >> plot(DAX.[, 3], ylab='accel (%)') >> >> >> This is what I want as three panels of a single plot. >> >> >> I think I could get it by modifying the code for plot.ts so it >> accepted ylab as a vector, etc., as I previously mentioned. >> >> >> What do you think? >> Thanks, >> Spencer Graves >>> >>> >>> On Tue, May 30, 2023 at 4:06?PM Spencer Graves >>> <spencer.graves at effectivedefense.org> wrote: >>>> >>>> >>>> >>>> On 5/30/23 6:16 AM, Eric Berger wrote: >>>>> My code assumes that DAX is a ts object, as in your original post. >>>>> >>>>> On Tue, May 30, 2023 at 2:06?PM Eric Berger <ericjberger at gmail.com> wrote: >>>>>> >>>>>> Untested but why not >>>>>> >>>>>> a <- cbind(log(DAX), exp(diff(log(DAX))), exp(diff(diff(log(DAX))))) >>>>>> colnames(a) <- c("logDAX", "vel", "accel") >>>>>> plot(a) >>>> >>>> >>>> Progress, but we're not there yet. >>>> >>>> >>>> a <- cbind(DAX, exp(diff(log(DAX))), exp(diff(diff(log(DAX))))) >>>> colnames(a) <- c("logDAX", "vel", "accel") >>>> plot(a) >>>> plot(a, axes=FALSE, log='y') >>>> axis(1) >>>> axis(2) >>>> >>>> >>>> How do I get each y axis labeled in its original units? I can use >>>> pretty to get where I want tick marks, but I don't know where to place >>>> them "at" in calling axis(2, at= ___)? >>>> >>>> >>>> (axlb1 <- pretty(range(a[, 1]))) >>>> (axlb2 <- pretty(range(log(a[, 2]), na.rm=TRUE))) >>>> (axlb3 <- pretty(range(log(a[, 3]), na.rm=TRUE))) >>>> >>>> >>>> This suggests I write my own modification of plot.ts that accepts log >>>> as a character vector of length = ncol of the ts being plotted and >>>> returns invisibly a list with the default "at" and "label" arguments >>>> required to produce the default labeling. Then a user who wants a log >>>> scale for some but not all variables can get that easily and can further >>>> modify any of those scales further if they don't like the default. >>>> >>>> >>>> ??? >>>> Thanks very much. >>>> Spencer Graves >>>>>> >>>>>> >>>>>> On Tue, May 30, 2023 at 1:46?PM Spencer Graves >>>>>> <spencer.graves at effectivedefense.org> wrote: >>>>>>> >>>>>>> >>>>>>> >>>>>>> On 5/29/23 2:37 AM, Eric Berger wrote: >>>>>>>> How about this: >>>>>>>> >>>>>>>> a <- cbind(AirPassengers, diff(log(AirPassengers)), >>>>>>>> diff(diff(log(AirPassengers)))) >>>>>>>> colnames(a)[2:3] <- c("percent increase", "acceleration") >>>>>>>> plot(a, xlab="year", main="AirPassengers") >>>>>>> >>>>>>> >>>>>>> My real problem is more difficult: I'm analyzing CO2 data from Our >>>>>>> World in Data (https://ourworldindata.org/co2-emissions), and I need to >>>>>>> plot the CO2 data on a log scale but velocity and acceleration on linear >>>>>>> scales. The following is comparable: >>>>>>> >>>>>>> >>>>>>> str(DAX <- EuStockMarkets[, 'DAX']) >>>>>>> str(DAX. <- cbind(DAX, diff(log(DAX)), >>>>>>> diff(diff(log(DAX))))) >>>>>>> colnames(DAX.)[2:3] <- c('vel', 'accel') >>>>>>> plot(DAX.) >>>>>>> >>>>>>> >>>>>>> I want the first of the three panels to plot on the log scale, but >>>>>>> the other two on linear scales. The obvious attempt does not work: >>>>>>> >>>>>>> >>>>>>> plot(DAX., log=c('y', '', '')) >>>>>>> #Error in length(log) && log != "" : >>>>>>> # 'length = 3' in coercion to 'logical(1)' >>>>>>> >>>>>>> >>>>>>> Trying to construct my own axes isn't easy, either: >>>>>>> >>>>>>> >>>>>>> str(logDAX <- cbind(log(DAX), diff(log(DAX)), >>>>>>> diff(diff(log(DAX))))) >>>>>>> colnames(logDAX) <- c('logDAX', 'vel', 'accel') >>>>>>> plot(logDAX, axes=FALSE) >>>>>>> axis(1) >>>>>>> axis(2) >>>>>>> >>>>>>> >>>>>>> I'm thinking of creating my own copy of "plot.ts", and changing it so >>>>>>> it accepts the "log" argument as a vector of length equal to ncol of the >>>>>>> ts object to be plotted AND returning an object that would allow a user >>>>>>> to call "axis" ncol times. >>>>>>> >>>>>>> >>>>>>> Suggestions? >>>>>>> >>>>>>> >>>>>>> Thanks, >>>>>>> Spencer Graves >>>>>>> >>>>>>>> >>>>>>>> HTH, >>>>>>>> Eric >>>>>>>> >>>>>>>> >>>>>>>> On Mon, May 29, 2023 at 7:57?AM Spencer Graves >>>>>>>> <spencer.graves at effectivedefense.org> wrote: >>>>>>>>> >>>>>>>>> Hello, All: >>>>>>>>> >>>>>>>>> >>>>>>>>> I want to plot level, velocity, and acceleration in three panels with >>>>>>>>> only one x axis. The code below does this using "layout". However, I >>>>>>>>> want the three plot areas to be of equal size, and this won't do that: >>>>>>>>> If I stretch the plot vertically, the relative sizes of the three panels >>>>>>>>> changes. There's probably a way to do this with ggplot2, but I have yet >>>>>>>>> to find it. >>>>>>>>> >>>>>>>>> >>>>>>>>> Suggestions? >>>>>>>>> Thanks, >>>>>>>>> Spencer Graves >>>>>>>>> >>>>>>>>> >>>>>>>>> str(AirTime <- as.numeric(time(AirPassengers))) >>>>>>>>> str(AP <- as.numeric(AirPassengers)) >>>>>>>>> >>>>>>>>> def.par <- par(no.readonly = TRUE) # save default, for resetting... >>>>>>>>> (mat3x1 <- matrix(1:3, 3)) >>>>>>>>> plot3x1 <- layout(mat3x1, heights=c(1.4, 1, 1.5)) >>>>>>>>> layout.show(plot3x1) >>>>>>>>> >>>>>>>>> par(mar=c(0, 4.1, 4.1, 2.1)) >>>>>>>>> plot(AirTime, AP, log='y', type='l', axes=FALSE, >>>>>>>>> main='AirPassengers', ylab='AirPassengers') >>>>>>>>> box(col='grey') >>>>>>>>> axis(2, las=1) >>>>>>>>> >>>>>>>>> par(mar=c(0, 4.1, 0, 2.1)) >>>>>>>>> vAP <- diff(log(AP)) >>>>>>>>> plot(tail(AirTime, -1), vAP, type='l', >>>>>>>>> ylab='percent increase', axes=FALSE) >>>>>>>>> box(col='grey') >>>>>>>>> axis(2, las=1) >>>>>>>>> >>>>>>>>> par(mar=c(5.1, 4.1, 0, 2.1)) >>>>>>>>> plot(tail(AirTime, -2), diff(vAP), type='l', >>>>>>>>> ylab='acceleration', xlab='year', >>>>>>>>> las=1) >>>>>>>>> box(col='grey') >>>>>>>>> >>>>>>>>> par(def.par) >>>>>>>>> >>>>>>>>> ______________________________________________ >>>>>>>>> R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see >>>>>>>>> https://stat.ethz.ch/mailman/listinfo/r-help >>>>>>>>> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html >>>>>>>>> and provide commented, minimal, self-contained, reproducible code.
I sent you an updated response to deal with the redundant copies of the x-axis. Re-sending. par(mfrow=c(3,1)) plot(DAX.[, 1], log='y', ylab='DAX', xaxt="n") plot(DAX.[, 2], ylab='vel (%)', xaxt="n") plot(DAX.[, 3], ylab='accel (%)') On Wed, May 31, 2023 at 4:27?PM Spencer Graves <spencer.graves at effectivedefense.org> wrote:> > > > On 5/30/23 10:23 AM, Eric Berger wrote: > > What if you just precede these commands as follows: > > > > par(mfrow=c(3,1)) > > plot(DAX.[, 1], log='y', ylab='DAX') > > plot(DAX.[, 2], ylab='vel (%)') > > plot(DAX.[, 3], ylab='accel (%)') > > Most of the space is consumed with two extraneous copies of the axis. > We can get around that with three calls to par: > > > op <- par(mfrow=c(3,1), mar=c(0, 4.1, 4.1, 2.1)) > plot(DAX.[, 1], log='y', ylab='DAX') > par(mar=c(0, 4.1, 0, 2.1)) > plot(DAX.[, 2], ylab='vel (%)') > par(mar=c(5.1, 4.1, 0, 2.1)) > plot(DAX.[, 3], ylab='accel (%)') > par(op) > > > However, the three panels are NOT equal in size: roughly 30% vs. 44% > vs. 26%. I can get closer using layout, but if I change the aspect > ratio, it changes the relationship between the heights of the three > panels. > > > That's the problem I'm trying to solve. It's also why it makes sense > to me to modify plot.ts to accept a vector for the log argument, with > the constraint that length(lot) = either 1 or ncol(x). > > > There may be a way to do it using gglot2 / the tidyverse, but I'm not > facile with that, and my web searches have so far failed to produce > anything better than modifying plot.ts.R (and then submitting such with > compatible changes to plot.ts.Rd), as I suggested earlier. > > > ??? > Thanks, > Spencer > > > > > On Tue, May 30, 2023 at 5:45?PM Spencer Graves > > <spencer.graves at effectivedefense.org> wrote: > >> > >> > >> > >> On 5/30/23 8:48 AM, Eric Berger wrote: > >>> I am a bit confused as to what you are trying to achieve - and even > >>> if I could guess it is not clear what the interpretation would be. > >>>> head(DAX) > >>> 1628.75 1613.63 1606.51 1621.04 1618.16 1610.61 > >>> > >>> Including the leading NA's, what would be the 6 leading terms of the 3 > >>> series that you want to plot, > >>> and what would be the Y labels that you want to appear at those levels > >>> (assuming that there was a > >>> Y label for each of them - just to understand the units you are talking about) > >> > >> > >> DAX <- EuStockMarkets[, 'DAX'] > >> DAX. <- cbind(DAX, diff(log(DAX)), diff(diff(log(DAX)))) > >> colnames(DAX.) <- c("DAX", 'vel (%)', 'accel (%)') > >> head(DAX.) > >> > >> > >> DAX exhibits growth that is roughly exponential, so I want to plot it > >> on a log scale: > >> > >> > >> plot(DAX.[, 1], log='y', ylab='DAX') > >> plot(DAX.[, 2], ylab='vel (%)') > >> plot(DAX.[, 3], ylab='accel (%)') > >> > >> > >> This is what I want as three panels of a single plot. > >> > >> > >> I think I could get it by modifying the code for plot.ts so it > >> accepted ylab as a vector, etc., as I previously mentioned. > >> > >> > >> What do you think? > >> Thanks, > >> Spencer Graves > >>> > >>> > >>> On Tue, May 30, 2023 at 4:06?PM Spencer Graves > >>> <spencer.graves at effectivedefense.org> wrote: > >>>> > >>>> > >>>> > >>>> On 5/30/23 6:16 AM, Eric Berger wrote: > >>>>> My code assumes that DAX is a ts object, as in your original post. > >>>>> > >>>>> On Tue, May 30, 2023 at 2:06?PM Eric Berger <ericjberger at gmail.com> wrote: > >>>>>> > >>>>>> Untested but why not > >>>>>> > >>>>>> a <- cbind(log(DAX), exp(diff(log(DAX))), exp(diff(diff(log(DAX))))) > >>>>>> colnames(a) <- c("logDAX", "vel", "accel") > >>>>>> plot(a) > >>>> > >>>> > >>>> Progress, but we're not there yet. > >>>> > >>>> > >>>> a <- cbind(DAX, exp(diff(log(DAX))), exp(diff(diff(log(DAX))))) > >>>> colnames(a) <- c("logDAX", "vel", "accel") > >>>> plot(a) > >>>> plot(a, axes=FALSE, log='y') > >>>> axis(1) > >>>> axis(2) > >>>> > >>>> > >>>> How do I get each y axis labeled in its original units? I can use > >>>> pretty to get where I want tick marks, but I don't know where to place > >>>> them "at" in calling axis(2, at= ___)? > >>>> > >>>> > >>>> (axlb1 <- pretty(range(a[, 1]))) > >>>> (axlb2 <- pretty(range(log(a[, 2]), na.rm=TRUE))) > >>>> (axlb3 <- pretty(range(log(a[, 3]), na.rm=TRUE))) > >>>> > >>>> > >>>> This suggests I write my own modification of plot.ts that accepts log > >>>> as a character vector of length = ncol of the ts being plotted and > >>>> returns invisibly a list with the default "at" and "label" arguments > >>>> required to produce the default labeling. Then a user who wants a log > >>>> scale for some but not all variables can get that easily and can further > >>>> modify any of those scales further if they don't like the default. > >>>> > >>>> > >>>> ??? > >>>> Thanks very much. > >>>> Spencer Graves > >>>>>> > >>>>>> > >>>>>> On Tue, May 30, 2023 at 1:46?PM Spencer Graves > >>>>>> <spencer.graves at effectivedefense.org> wrote: > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> On 5/29/23 2:37 AM, Eric Berger wrote: > >>>>>>>> How about this: > >>>>>>>> > >>>>>>>> a <- cbind(AirPassengers, diff(log(AirPassengers)), > >>>>>>>> diff(diff(log(AirPassengers)))) > >>>>>>>> colnames(a)[2:3] <- c("percent increase", "acceleration") > >>>>>>>> plot(a, xlab="year", main="AirPassengers") > >>>>>>> > >>>>>>> > >>>>>>> My real problem is more difficult: I'm analyzing CO2 data from Our > >>>>>>> World in Data (https://ourworldindata.org/co2-emissions), and I need to > >>>>>>> plot the CO2 data on a log scale but velocity and acceleration on linear > >>>>>>> scales. The following is comparable: > >>>>>>> > >>>>>>> > >>>>>>> str(DAX <- EuStockMarkets[, 'DAX']) > >>>>>>> str(DAX. <- cbind(DAX, diff(log(DAX)), > >>>>>>> diff(diff(log(DAX))))) > >>>>>>> colnames(DAX.)[2:3] <- c('vel', 'accel') > >>>>>>> plot(DAX.) > >>>>>>> > >>>>>>> > >>>>>>> I want the first of the three panels to plot on the log scale, but > >>>>>>> the other two on linear scales. The obvious attempt does not work: > >>>>>>> > >>>>>>> > >>>>>>> plot(DAX., log=c('y', '', '')) > >>>>>>> #Error in length(log) && log != "" : > >>>>>>> # 'length = 3' in coercion to 'logical(1)' > >>>>>>> > >>>>>>> > >>>>>>> Trying to construct my own axes isn't easy, either: > >>>>>>> > >>>>>>> > >>>>>>> str(logDAX <- cbind(log(DAX), diff(log(DAX)), > >>>>>>> diff(diff(log(DAX))))) > >>>>>>> colnames(logDAX) <- c('logDAX', 'vel', 'accel') > >>>>>>> plot(logDAX, axes=FALSE) > >>>>>>> axis(1) > >>>>>>> axis(2) > >>>>>>> > >>>>>>> > >>>>>>> I'm thinking of creating my own copy of "plot.ts", and changing it so > >>>>>>> it accepts the "log" argument as a vector of length equal to ncol of the > >>>>>>> ts object to be plotted AND returning an object that would allow a user > >>>>>>> to call "axis" ncol times. > >>>>>>> > >>>>>>> > >>>>>>> Suggestions? > >>>>>>> > >>>>>>> > >>>>>>> Thanks, > >>>>>>> Spencer Graves > >>>>>>> > >>>>>>>> > >>>>>>>> HTH, > >>>>>>>> Eric > >>>>>>>> > >>>>>>>> > >>>>>>>> On Mon, May 29, 2023 at 7:57?AM Spencer Graves > >>>>>>>> <spencer.graves at effectivedefense.org> wrote: > >>>>>>>>> > >>>>>>>>> Hello, All: > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> I want to plot level, velocity, and acceleration in three panels with > >>>>>>>>> only one x axis. The code below does this using "layout". However, I > >>>>>>>>> want the three plot areas to be of equal size, and this won't do that: > >>>>>>>>> If I stretch the plot vertically, the relative sizes of the three panels > >>>>>>>>> changes. There's probably a way to do this with ggplot2, but I have yet > >>>>>>>>> to find it. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> Suggestions? > >>>>>>>>> Thanks, > >>>>>>>>> Spencer Graves > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> str(AirTime <- as.numeric(time(AirPassengers))) > >>>>>>>>> str(AP <- as.numeric(AirPassengers)) > >>>>>>>>> > >>>>>>>>> def.par <- par(no.readonly = TRUE) # save default, for resetting... > >>>>>>>>> (mat3x1 <- matrix(1:3, 3)) > >>>>>>>>> plot3x1 <- layout(mat3x1, heights=c(1.4, 1, 1.5)) > >>>>>>>>> layout.show(plot3x1) > >>>>>>>>> > >>>>>>>>> par(mar=c(0, 4.1, 4.1, 2.1)) > >>>>>>>>> plot(AirTime, AP, log='y', type='l', axes=FALSE, > >>>>>>>>> main='AirPassengers', ylab='AirPassengers') > >>>>>>>>> box(col='grey') > >>>>>>>>> axis(2, las=1) > >>>>>>>>> > >>>>>>>>> par(mar=c(0, 4.1, 0, 2.1)) > >>>>>>>>> vAP <- diff(log(AP)) > >>>>>>>>> plot(tail(AirTime, -1), vAP, type='l', > >>>>>>>>> ylab='percent increase', axes=FALSE) > >>>>>>>>> box(col='grey') > >>>>>>>>> axis(2, las=1) > >>>>>>>>> > >>>>>>>>> par(mar=c(5.1, 4.1, 0, 2.1)) > >>>>>>>>> plot(tail(AirTime, -2), diff(vAP), type='l', > >>>>>>>>> ylab='acceleration', xlab='year', > >>>>>>>>> las=1) > >>>>>>>>> box(col='grey') > >>>>>>>>> > >>>>>>>>> par(def.par) > >>>>>>>>> > >>>>>>>>> ______________________________________________ > >>>>>>>>> R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > >>>>>>>>> https://stat.ethz.ch/mailman/listinfo/r-help > >>>>>>>>> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > >>>>>>>>> and provide commented, minimal, self-contained, reproducible code.