diff --git a/.gitignore b/.gitignore index 457525e..434c868 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ .DS_Store .quarto docs +CRAN-SUBMISSION diff --git a/CRAN-SUBMISSION b/CRAN-SUBMISSION deleted file mode 100644 index 73b87fd..0000000 --- a/CRAN-SUBMISSION +++ /dev/null @@ -1,3 +0,0 @@ -Version: 3.8-4 -Date: 2023-11-09 16:39:39 UTC -SHA: c3a952da92f2551f49082dd2461da7c0093cbf81 diff --git a/DESCRIPTION b/DESCRIPTION index fe81957..cf3518d 100755 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,5 +1,5 @@ Package: plotrix -Version: 3.8-7 +Version: 3.8-14 Title: Various Plotting Functions Authors@R: c( person("Jim", "Lemon", role = "aut"), diff --git a/NEWS b/NEWS index 0d34dde..ce10d22 100755 --- a/NEWS +++ b/NEWS @@ -1,6 +1,18 @@ -Changes in version 3.8-7 (2025-11-12) +Changes in version 3.8.14 (2026-02-13) + + - Fixed mis-handling of `labels = ""` in `polar.plot()` (issue #19). + +Changes in version 3.8-13 (2025-11-14) - Fixed warnings in `gap.plot()` when there were 2 gaps. + + - Fixed `pie3D()` which skipped very small slices (issue #9). + - Fixed `polar.plot()` which put labels in the wrong place (PR #8). + + - Fixed `plotCI()` to allow `pch` to be a vector (PR #11). + + - Added arguments to `gap.plot()` to support non-standard + box types (PR #17). Changes in version 3.8-6 (2023-11-13) diff --git a/R/gap.plot.R b/R/gap.plot.R index b7f48ca..07aa462 100644 --- a/R/gap.plot.R +++ b/R/gap.plot.R @@ -8,7 +8,7 @@ gap.plot<-function(x,y,gap,gap.axis="y",bgcol="white",breakcol="black", brw=0.02,xlim=range(x),ylim=range(y),xticlab,xtics=NA,yticlab,ytics=NA, lty=rep(1,length(x)),col=rep(par("col"),length(x)),pch=rep(1,length(x)), - add=FALSE,stax=FALSE,...) { + add=FALSE,stax=FALSE,style="gap",bty=par("bty"),xaxt=par("xaxt"),yaxt=par("yaxt"),...) { if(missing(y) && !missing(x)) { y<-x @@ -104,9 +104,9 @@ gap.plot<-function(x,y,gap,gap.axis="y",bgcol="white",breakcol="black", else { plot(x[littleones],y[littleones],xlim=xlim,ylim=ylim,axes=FALSE, lty=lty[littleones],col=col[littleones],pch=pch[littleones],...) - box() + box(bty=bty) if(gap.axis == "y") { - if(!is.na(xtics[1])) axis(1,at=xtics,labels=xticlab) + if(!is.na(xtics[1])) axis(1,at=xtics,labels=xticlab,xaxt=xaxt) littletics<-which(ytics < gap[1]) if(length(gapsize) > 2) { middletics<-which(ytics >= gap[2]+ygw[1] & ytics <= gap[3]) @@ -125,10 +125,10 @@ gap.plot<-function(x,y,gap,gap.axis="y",bgcol="white",breakcol="black", staxlab(2,at=show.at,labels=show.labels) } else axis(2,at=show.at,labels=show.labels) - axis.break(2,gap[1],style="gap",bgcol=bgcol, + axis.break(2,gap[1],style=style,bgcol=bgcol, breakcol=breakcol,brw=brw) if(length(gapsize) > 2) { - axis.break(2,gap[3]-gapsize[1],style="gap",bgcol=bgcol, + axis.break(2,gap[3]-gapsize[1],style=style,bgcol=bgcol, breakcol=breakcol,brw=brw) points(x[middleones],y[middleones]-gapsize[1], lty=lty[middleones],col=col[middleones],pch=pch[middleones],...) @@ -140,7 +140,7 @@ gap.plot<-function(x,y,gap,gap.axis="y",bgcol="white",breakcol="black", } # x gaps need to be fixed else { - if(!is.na(ytics[1])) axis(2,at=ytics,labels=yticlab) + if(!is.na(ytics[1])) axis(2,at=ytics,labels=yticlab,yaxt=yaxt) littletics<-which(xtics < gap[1]) if(length(gapsize) > 2) { middletics<-which(xtics >= gap[2] + xgw[1] & xtics <= gap[3]) @@ -159,9 +159,9 @@ gap.plot<-function(x,y,gap,gap.axis="y",bgcol="white",breakcol="black", staxlab(1,at=show.at,labels=show.labels) } else axis(1,at=show.at,labels=show.labels) - axis.break(1,gap[1],style="gap") + axis.break(1,gap[1],style=style) if(length(gapsize) > 2) { - axis.break(1,gap[3]-gapsize[1],style="gap") + axis.break(1,gap[3]-gapsize[1],style=style) points(x[middleones]-gapsize[1],y[middleones], lty=lty[middleones],col=col[middleones],pch=pch[middleones],...) points(x[bigones]-(gapsize[1]+gapsize[3]),y[bigones], diff --git a/R/pie3D.R b/R/pie3D.R index 69fe8e7..f9193d9 100644 --- a/R/pie3D.R +++ b/R/pie3D.R @@ -26,7 +26,7 @@ draw.tilted.sector<-function(x=0,y=0,edges=NA,radius=1,height=0.1, theta=pi/6,start=0,end=pi*2,border=par("fg"),col=par("bg"),explode=0, shade=0.8) { - if(is.na(edges)) edges<-trunc(20*(end-start)) + if(is.na(edges)) edges<-max(1, trunc(20*(end-start))) angleinc<-(end-start)/edges angles<-c(seq(start,end,by=angleinc),end) viscurve<-(angles>=pi)&(angles<=2*pi) diff --git a/R/plotCI.R b/R/plotCI.R index 348691b..001af98 100644 --- a/R/plotCI.R +++ b/R/plotCI.R @@ -36,7 +36,7 @@ plotCI <- function (x, y = NULL, uiw, liw = uiw, ui = NULL, li = NULL, else scol <- par("col") } plotpoints <- TRUE - if (!is.null(arglist$pch) && is.na(arglist$pch)) { + if (!is.null(arglist$pch) && any(is.na(arglist$pch))) { arglist$pch <- 1 plotpoints <- FALSE } diff --git a/R/radial.plot.R b/R/radial.plot.R index ef92397..b9c15a4 100755 --- a/R/radial.plot.R +++ b/R/radial.plot.R @@ -41,8 +41,10 @@ polar.plot<-function(lengths,polar.pos=NULL,labels,label.pos=NULL, if(start) start<-pi*start/180 if(missing(labels)) { labels<-label.pos<-seq(0,340,by=20) - label.pos<-pi*label.pos/180 - } + } else if (length(labels) == 1 && labels == "") + label.pos <- NULL + if(!is.null(label.pos)) + label.pos <- pi*label.pos/180 invisible(radial.plot(lengths,radial.pos,labels,label.pos,start=start, clockwise=clockwise,rp.type=rp.type,loglen=loglen,explab=explab,...)) } diff --git a/cran-comments.md b/cran-comments.md index 125c236..5278e98 100644 --- a/cran-comments.md +++ b/cran-comments.md @@ -1,7 +1,22 @@ +## 3.8-13 -* This is mainly a release to set myself as the new maintainer. -* It also fixes one bug that was reported on Jim Lemon's Github site, - and removes one line from an example that caused an error in the - "check donttest" tests. -* I haven't run revdep checks; they would take hours here, and changes -are pretty minimal. + - Fixes CRAN issues: URL moved, width of usage. + +## 3.8-12 + +This is a fairly minor bug fix release. It also adds a few +options to the `gap.plot()` function. Here's the news: + + - Fixed warnings in `gap.plot()` when there were 2 gaps. + + - Fixed `pie3D()` which skipped very small slices (issue #9). + - Fixed `polar.plot()` which put labels in the wrong place (PR #8). + + - Fixed `plotCI()` to allow `pch` to be a vector (PR #11). + + - Added arguments to `gap.plot()` to support non-standard + box types (PR #17). + + - Added pkgdown site at https://plotrix.github.io/plotrix/ + + - Changed `Authors` to more descriptive `Authors@R`. diff --git a/man/gap.plot.Rd b/man/gap.plot.Rd index 679307a..8c9539c 100644 --- a/man/gap.plot.Rd +++ b/man/gap.plot.Rd @@ -5,10 +5,12 @@ Displays a plot with one or two missing ranges on one of the axes. } \usage{ - gap.plot(x,y,gap,gap.axis="y",bgcol="white",breakcol="black",brw=0.02, - xlim=range(x),ylim=range(y),xticlab,xtics=NA,yticlab,ytics=NA, - lty=rep(1,length(x)),col=rep(par("col"),length(x)),pch=rep(1,length(x)), - add=FALSE,stax=FALSE,...) +gap.plot(x,y,gap,gap.axis="y", + bgcol="white",breakcol="black",brw=0.02, + xlim=range(x),ylim=range(y),xticlab,xtics=NA,yticlab,ytics=NA, + lty=rep(1,length(x)),col=rep(par("col"),length(x)),pch=rep(1,length(x)), + add=FALSE,stax=FALSE, + style="gap",bty=par("bty"),xaxt=par("xaxt"),yaxt=par("yaxt"),...) } \arguments{ \item{x,y}{data values} @@ -27,6 +29,8 @@ \item{pch}{symbols to use in plotting.} \item{add}{whether to add values to an existing plot.} \item{stax}{whether to call staxlab for staggered axis labels.} + \item{style}{the style to use for the break; see \code{\link{axis.break}}} + \item{bty,xaxt,yaxt}{type of box and axes (see \code{\link{par}} for details.)} \item{...}{arguments passed to \samp{plot} and \samp{points}.} } \value{nil} @@ -83,5 +87,10 @@ type="b") gap.plot(21:30,rnorm(10)+40,gap=c(8,16,25,35),add=TRUE, lty=rep(3,10),col=rep(4,10),type="l") + + # Use non-standard box type and break + gap.plot(twogrp,gap=c(7,17),xlab="Index",ylab="Group values", + main="Gap on Y axis",col=gpcol,bty="L",style="slash", + ytics=pretty(twogrp, 8)) } \keyword{misc} diff --git a/man/multivari.Rd b/man/multivari.Rd index 3ed9870..3c80dcc 100755 --- a/man/multivari.Rd +++ b/man/multivari.Rd @@ -1,156 +1,156 @@ -\name{multivari} -\alias{multivari} -\title{ -Function to draw a multivari chart -} -\description{ -A multivari chart of one quantitative response variable depending on two -to four categorical variables can be drawn. -} -\usage{ -multivari(var, fac1, fac2, fac3 = NULL, fac4 = NULL, data, sort = FALSE, - fun = mean, pch = list(15, 16, 17), col = list("black", "blue", "red"), - col0 = "black", cex = 1, fac.cex = 2, xlab.depth = 3, legend = FALSE, - main = paste("multivari chart of", var), add = FALSE, ...) -} -%- maybe also 'usage' for other objects documented here. -\arguments{ - \item{var}{variable name (character string) or column index of response - variable, required -} - \item{fac1}{variable name (character string) or column index of first - level factor, required; precedes \code{fac2} and \code{fac3} (if present) in the hierarchy (see Details) -} - \item{fac2}{variable name (character string) or column index of second - level factor, required; follows \code{fac1} and precedes \code{fac3} (if present) - in the hierarchy (see Details) -} - \item{fac3}{variable name (character string) or column index of third - level factor, optional; if present, \code{fac3} is the last factor in the hierarchy (see Details) -} - \item{fac4}{ -variable name (character string) or column index of fourth level factor, -optional; can only be specified if there is also a third level factor; -if present, this factor is the first in the hierarchy (see Details), and separate multivari charts for the first three factors are drawn for each level of this factor} - \item{data}{ -a data frame, required -} - \item{sort}{ -logical, specifying whether or not levels are sorted, when converting -character vectors to factors (a single choice for all factors is needed); default: \code{FALSE} -} - \item{fun}{ -a function to be used in aggregation; default: \code{mean} -} - \item{pch}{ - a list of length 2 or 3, depending on whether or not \code{fac3} is - specified; the ith list element can be an individual plotting symbol - (like the usual \code{pch} entry) or a vector of plot symbols for each - level of \code{fac_i} -} - \item{col}{ - a list of length 2 or 3, depending on whether or not \code{fac3} is - specified; the ith list element can be an individual color or a vector - of colors for each level of \code{fac_i}; this color specification is - used for the plot symbols of \code{fac_i} levels and for the lines - connecting the symbols for the next level in the hierarchy -} - \item{col0}{ -the color for the first line to be drawn -} - \item{cex}{ -the size of axis annotation text -(annotation of the fourth level header is 1.5 times this size) -} - \item{fac.cex}{ -a multiplier for \code{cex}; plot symbol sizes are \code{fac.cex*cex}; -default: 2 -} - \item{xlab.depth}{ -labels for the horizontal axis are printed down to this level of the -hierarchy (default: 3); if the depth is reduced, different plot symbols -should be used, and a legend should be drawn -} - \item{legend}{ -logical determining whether or not a legend should be drawn (default: -FALSE); the function determines wether top right or bottom right yields -a better position (it is not guaranteed that there is no overlab); if -this does not work well, one can manually draw a legend in the outer -margin -} - \item{main}{ -title, as usual; a default is provided -} - \item{add}{ -logical; add to an existing plot (which of course has to have suitable axis limits)?; default: FALSE; -note that horizontal axis labeling will always be printed by function multivari, while vertical axis labeling will be omitted for \code{add=TRUE} -} - \item{\dots}{ -further arguments to functions \code{plot}, \code{lines}, \code{points}, - \code{mtext} -} -} -\details{ -The function is inspired by Minitabs behavior for multivari charts -(see also Bruno Scibilia's blog which is linked in the references). It -does not attempt to visualize individual observations. - -A multivari chart mainly serves exploratory purposes. -It works particularly well with balanced data, but can also be used for messy data. -\code{multivari} can visualize the dependence of a single quantitative variable on up to four factors (i.e., interactions of order up to four can be visualized). The display is hierarchical: for factors later in the hierarchy, conditional means given level combinations of factors earlier in the hierarchy are displayed. Therefore, the order of the -factors can make a big difference in the display. If there is no natural -order, it may be worthwhile to inspect several orders. - -For interactions with two factors only, it is often preferrable to use -function \code{\link{interaction.plot}} or \code{\link{raw.means.plot}}. - -} -\value{ -a list of (lists of) data frames with summary statistics to be plotted -} - -\references{ -Scibilia, Bruno (2013). Using Multi-Vari Charts to Analyze Families of Variations. \url{https://blog.minitab.com/en/using-variability-charts-to-analyze-call-center-wait-times}. -} - -\author{ -Ulrike Groemping -} -\seealso{ -See also \code{\link{interaction.plot}}, \code{\link{raw.means.plot}} -} -\examples{ -##---- Should be DIRECTLY executable !! ---- -##-- ==> Define data, use random, -##-- or do help(data=index) for the standard data sets. -\dontrun{ -require(car) -multivari("cycles", "len", "load", "amp", data=Wool, - col=list("black","red",c("grey70","grey45","grey20")), - pch=list(15,17,8), legend=TRUE, xlab.depth = 2, lwd=2) -multivari("cycles", "load", "len", "amp", data=Wool, - col=list("black",c("red","blue","darkgreen"), - c("grey70","grey45","grey20")), - pch=list(15,17,8), legend=TRUE, xlab.depth = 2, lwd=2) - -## create a fake fourth factor -fakedat <- rbind(cbind(newfac="blabla",Wool),cbind(newfac="albalb",Wool)) -## make it character for demonstrating the effect of sort option -fakedat$newfac <- as.character(fakedat$newfac) - -## default: sort order in the data is respected (order of unique is used) -multivari("cycles", "load", "len", "amp", "newfac", data=fakedat, - col=list("black",c("red","blue","darkgreen"), - c("grey70","grey45","grey20")), - pch=list(15,17,8), legend=TRUE, xlab.depth = 2, lwd=2, cex=0.8) - -## sort=TRUE: levels are sorted (order of sort(unique)) -multivari("cycles", "load", "len", "amp", "newfac", data=fakedat, - col=list("black",c("red","blue","darkgreen"), - c("grey70","grey45","grey20")), - pch=list(15,17,8), legend=TRUE, xlab.depth = 2, lwd=2, cex=0.8, - sort=TRUE) -} -} -\keyword{ hplot } -\keyword{ design } +\name{multivari} +\alias{multivari} +\title{ +Function to draw a multivari chart +} +\description{ +A multivari chart of one quantitative response variable depending on two +to four categorical variables can be drawn. +} +\usage{ +multivari(var, fac1, fac2, fac3 = NULL, fac4 = NULL, data, sort = FALSE, + fun = mean, pch = list(15, 16, 17), col = list("black", "blue", "red"), + col0 = "black", cex = 1, fac.cex = 2, xlab.depth = 3, legend = FALSE, + main = paste("multivari chart of", var), add = FALSE, ...) +} +%- maybe also 'usage' for other objects documented here. +\arguments{ + \item{var}{variable name (character string) or column index of response + variable, required +} + \item{fac1}{variable name (character string) or column index of first + level factor, required; precedes \code{fac2} and \code{fac3} (if present) in the hierarchy (see Details) +} + \item{fac2}{variable name (character string) or column index of second + level factor, required; follows \code{fac1} and precedes \code{fac3} (if present) + in the hierarchy (see Details) +} + \item{fac3}{variable name (character string) or column index of third + level factor, optional; if present, \code{fac3} is the last factor in the hierarchy (see Details) +} + \item{fac4}{ +variable name (character string) or column index of fourth level factor, +optional; can only be specified if there is also a third level factor; +if present, this factor is the first in the hierarchy (see Details), and separate multivari charts for the first three factors are drawn for each level of this factor} + \item{data}{ +a data frame, required +} + \item{sort}{ +logical, specifying whether or not levels are sorted, when converting +character vectors to factors (a single choice for all factors is needed); default: \code{FALSE} +} + \item{fun}{ +a function to be used in aggregation; default: \code{mean} +} + \item{pch}{ + a list of length 2 or 3, depending on whether or not \code{fac3} is + specified; the ith list element can be an individual plotting symbol + (like the usual \code{pch} entry) or a vector of plot symbols for each + level of \code{fac_i} +} + \item{col}{ + a list of length 2 or 3, depending on whether or not \code{fac3} is + specified; the ith list element can be an individual color or a vector + of colors for each level of \code{fac_i}; this color specification is + used for the plot symbols of \code{fac_i} levels and for the lines + connecting the symbols for the next level in the hierarchy +} + \item{col0}{ +the color for the first line to be drawn +} + \item{cex}{ +the size of axis annotation text +(annotation of the fourth level header is 1.5 times this size) +} + \item{fac.cex}{ +a multiplier for \code{cex}; plot symbol sizes are \code{fac.cex*cex}; +default: 2 +} + \item{xlab.depth}{ +labels for the horizontal axis are printed down to this level of the +hierarchy (default: 3); if the depth is reduced, different plot symbols +should be used, and a legend should be drawn +} + \item{legend}{ +logical determining whether or not a legend should be drawn (default: +FALSE); the function determines wether top right or bottom right yields +a better position (it is not guaranteed that there is no overlab); if +this does not work well, one can manually draw a legend in the outer +margin +} + \item{main}{ +title, as usual; a default is provided +} + \item{add}{ +logical; add to an existing plot (which of course has to have suitable axis limits)?; default: FALSE; +note that horizontal axis labeling will always be printed by function multivari, while vertical axis labeling will be omitted for \code{add=TRUE} +} + \item{\dots}{ +further arguments to functions \code{plot}, \code{lines}, \code{points}, + \code{mtext} +} +} +\details{ +The function is inspired by Minitabs behavior for multivari charts +(see also Bruno Scibilia's blog which is linked in the references). It +does not attempt to visualize individual observations. + +A multivari chart mainly serves exploratory purposes. +It works particularly well with balanced data, but can also be used for messy data. +\code{multivari} can visualize the dependence of a single quantitative variable on up to four factors (i.e., interactions of order up to four can be visualized). The display is hierarchical: for factors later in the hierarchy, conditional means given level combinations of factors earlier in the hierarchy are displayed. Therefore, the order of the +factors can make a big difference in the display. If there is no natural +order, it may be worthwhile to inspect several orders. + +For interactions with two factors only, it is often preferrable to use +function \code{\link{interaction.plot}} or \code{\link{raw.means.plot}}. + +} +\value{ +a list of (lists of) data frames with summary statistics to be plotted +} + +\references{ +Scibilia, Bruno (2013). Using Multi-Vari Charts to Analyze Families of Variations. \url{https://blog.minitab.com/en/blog/using-variability-charts-to-analyze-call-center-wait-times}. +} + +\author{ +Ulrike Groemping +} +\seealso{ +See also \code{\link{interaction.plot}}, \code{\link{raw.means.plot}} +} +\examples{ +##---- Should be DIRECTLY executable !! ---- +##-- ==> Define data, use random, +##-- or do help(data=index) for the standard data sets. +\dontrun{ +require(car) +multivari("cycles", "len", "load", "amp", data=Wool, + col=list("black","red",c("grey70","grey45","grey20")), + pch=list(15,17,8), legend=TRUE, xlab.depth = 2, lwd=2) +multivari("cycles", "load", "len", "amp", data=Wool, + col=list("black",c("red","blue","darkgreen"), + c("grey70","grey45","grey20")), + pch=list(15,17,8), legend=TRUE, xlab.depth = 2, lwd=2) + +## create a fake fourth factor +fakedat <- rbind(cbind(newfac="blabla",Wool),cbind(newfac="albalb",Wool)) +## make it character for demonstrating the effect of sort option +fakedat$newfac <- as.character(fakedat$newfac) + +## default: sort order in the data is respected (order of unique is used) +multivari("cycles", "load", "len", "amp", "newfac", data=fakedat, + col=list("black",c("red","blue","darkgreen"), + c("grey70","grey45","grey20")), + pch=list(15,17,8), legend=TRUE, xlab.depth = 2, lwd=2, cex=0.8) + +## sort=TRUE: levels are sorted (order of sort(unique)) +multivari("cycles", "load", "len", "amp", "newfac", data=fakedat, + col=list("black",c("red","blue","darkgreen"), + c("grey70","grey45","grey20")), + pch=list(15,17,8), legend=TRUE, xlab.depth = 2, lwd=2, cex=0.8, + sort=TRUE) +} +} +\keyword{ hplot } +\keyword{ design }