I am creating a timeline plot, but running into a problem in positions where the values to plot are too close together to print the text without overlap. The simplest way I can think of to solve this (although there may be other ways?) is to create a new numeric vector whose values are as close as possible to the original vector, but spread out to a given minimum difference. For example, take the following vector:> x <- c(1,2,seq(2.1,2.3,0.1),3,4) > x[1] 1.0 2.0 2.1 2.2 2.3 3.0 4.0>However, suppose I don't want to plot any of these points with less than 0.5 between them. The problem could be solved by a function that behaved something like this:> x2 <- spread(x,mindiff=0.5) > x2[1] 0.5 1.0 1.5 2.0 2.5 3.0 4.0 Or for a minimum difference of 0.2,> x2 <- spread(x,mindiff=0.2) > x2[1] 1.0 1.8 2.0 2.2 2.4 3.0 4.0 Thus, if there is a cluster of close values, spreading the values may require changing values which previously weren't too close to their nearest neighbors. Then I could use segments() to draw lines from the timeline to where the shifted text is printed, labeling tics on the timeline accurately but keeping the text from overlapping. Any ideas on how to program this or how to do it using built-in functions would be greatly appreciated.
Is this close to what you want?> spread <- function(x, mindiff=0.5){+ unique(as.integer(x / mindiff) * mindiff) + }> > x <- c(1,2,seq(2.1,2.3,0.1),3,4) > x[1] 1.0 2.0 2.1 2.2 2.3 3.0 4.0> spread(x)[1] 1 2 3 4> > spread(x,.2)[1] 1.0 2.0 2.2 3.0 4.0>On Sat, Mar 22, 2008 at 8:03 PM, Levi Waldron <leviwaldron at gmail.com> wrote:> I am creating a timeline plot, but running into a problem in positions > where the values to plot are too close together to print the text > without overlap. The simplest way I can think of to solve this > (although there may be other ways?) is to create a new numeric vector > whose values are as close as possible to the original vector, but > spread out to a given minimum difference. For example, take the > following vector: > > > x <- c(1,2,seq(2.1,2.3,0.1),3,4) > > x > [1] 1.0 2.0 2.1 2.2 2.3 3.0 4.0 > > > > However, suppose I don't want to plot any of these points with less > than 0.5 between them. The problem could be solved by a function that > behaved something like this: > > > x2 <- spread(x,mindiff=0.5) > > x2 > [1] 0.5 1.0 1.5 2.0 2.5 3.0 4.0 > > Or for a minimum difference of 0.2, > > x2 <- spread(x,mindiff=0.2) > > x2 > [1] 1.0 1.8 2.0 2.2 2.4 3.0 4.0 > > Thus, if there is a cluster of close values, spreading the values may > require changing values which previously weren't too close to their > nearest neighbors. > > Then I could use segments() to draw lines from the timeline to where > the shifted text is printed, labeling tics on the timeline accurately > but keeping the text from overlapping. > > Any ideas on how to program this or how to do it using built-in > functions would be greatly appreciated. > > ______________________________________________ > R-help at r-project.org mailing list > 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. >-- Jim Holtman Cincinnati, OH +1 513 646 9390 What is the problem you are trying to solve?
Levi Waldron wrote:> I am creating a timeline plot, but running into a problem in positions > where the values to plot are too close together to print the text > without overlap...Hi Levi, This may not be what you want, but spread.labels in the plotrix package tries to evenly space labels for unevenly spaced points. Jim
Levi, Here is one possible function: spread <- function(x, mindiff) { df <- x[-1] - x[-length(x)] i <- 1 while (any(df < mindiff)) { x[c(df < mindiff, FALSE)] <- x[c(df < mindiff, FALSE)] - mindiff/10 x[c(FALSE, df < mindiff)] <- x[c(FALSE, df < mindiff)] + mindiff/10 df <- x[-1] - x[-length(x)] i <- i + 1 if (i > 100) { break } } x } I have tried experimenting with using optim to minimize a function of the distances between new points and old points penealized for being to close, but it sometimes gave me some weird results, the above has worked fairly well for me (the above is based on some of the code inside the triplot function in the TeachingDemos package). Hope this helps, -- Gregory (Greg) L. Snow Ph.D. Statistical Data Center Intermountain Healthcare greg.snow at imail.org (801) 408-8111> -----Original Message----- > From: r-help-bounces at r-project.org > [mailto:r-help-bounces at r-project.org] On Behalf Of Levi Waldron > Sent: Saturday, March 22, 2008 7:03 PM > To: R-help mailing list > Subject: [R] "spreading out" a numeric vector > > I am creating a timeline plot, but running into a problem in > positions where the values to plot are too close together to > print the text without overlap. The simplest way I can think > of to solve this (although there may be other ways?) is to > create a new numeric vector whose values are as close as > possible to the original vector, but spread out to a given > minimum difference. For example, take the following vector: > > > x <- c(1,2,seq(2.1,2.3,0.1),3,4) > > x > [1] 1.0 2.0 2.1 2.2 2.3 3.0 4.0 > > > > However, suppose I don't want to plot any of these points > with less than 0.5 between them. The problem could be solved > by a function that behaved something like this: > > > x2 <- spread(x,mindiff=0.5) > > x2 > [1] 0.5 1.0 1.5 2.0 2.5 3.0 4.0 > > Or for a minimum difference of 0.2, > > x2 <- spread(x,mindiff=0.2) > > x2 > [1] 1.0 1.8 2.0 2.2 2.4 3.0 4.0 > > Thus, if there is a cluster of close values, spreading the > values may require changing values which previously weren't > too close to their nearest neighbors. > > Then I could use segments() to draw lines from the timeline > to where the shifted text is printed, labeling tics on the > timeline accurately but keeping the text from overlapping. > > Any ideas on how to program this or how to do it using > built-in functions would be greatly appreciated. > > ______________________________________________ > R-help at r-project.org mailing list > 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. >