PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Wednesday, April 27, 2022

[FIXED] What does "collapsing to unique 'x' values" mean in this example?

 April 27, 2022     ggplot2, r, unique, warnings     No comments   

Issue

The example plot below produces a warning about

In regularize.values(x, y, ties, missing(ties), na.rm = na.rm) :
  collapsing to unique 'x' values

and I cannot figure out what that means in my example.

It must be related to the 5, because the warning disappears when replacing 5 by 4 or 1.

df <- data.frame(x = 1, y = c(0, 0.25, 0.5, 0.75, 5))
ggplot2::ggplot(df, ggplot2::aes(x = x, y = y)) +
    ggplot2::geom_violin(draw_quantiles = c(0.5))

What is going on here?


Solution

@teunbrand confirmed my hypothesis that

ecdf <- stats::approxfun(dens, data$y) 

(https://github.com/tidyverse/ggplot2/blob/cc3951cd942d/R/geom-violin.r#L200) is to blame.

Zeros in the density of the data$y translate into equal values ("ties") in the cumulative density dens - hence the warning.

These zeros can be avoided by adjusting the bandwidth of the density (here, slightly - in my example, I need to use a value as large as 3):

df <- data.frame(x = 1, y = c(0, 0.25, 0.5, 0.75, 5))
ggplot2::ggplot(df, ggplot2::aes(x = x, y = y)) +
    ggplot2::geom_violin(draw_quantiles = c(0.5), adjust=1.1)

Note: that code is hard to read due to niceties such as using dens for the cumulative density.

But stats::regularize.values is not necessarily better:

    x <- xy.coords(x, y) # -> (x,y) numeric of same length
    y <- x$y
    x <- x$x

The problem also can be fixed by

ecdf <- stats::approxfun(dens, data$y, ties = "ordered") 

as in this monkey patch:

create_quantile_segment_frame <- function(data, draw_quantiles) {
  dens <- cumsum(data$density) / sum(data$density)
  ecdf <- stats::approxfun(dens, data$y, ties = "ordered")
  ys <- ecdf(draw_quantiles) # these are all the y-values for quantiles

  # Get the violin bounds for the requested quantiles.
  violin.xminvs <- (stats::approxfun(data$y, data$xminv))(ys)
  violin.xmaxvs <- (stats::approxfun(data$y, data$xmaxv))(ys)

  # We have two rows per segment drawn. Each segment gets its own group.
  ggplot2:::new_data_frame(list(
    x = ggplot2:::interleave(violin.xminvs, violin.xmaxvs),
    y = rep(ys, each = 2),
    group = rep(ys, each = 2)
  ))
}
assignInNamespace("create_quantile_segment_frame", create_quantile_segment_frame, "ggplot2")

df <- data.frame(x = 1, y = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10))
ggplot2::ggplot(df, ggplot2::aes(x = x, y = y)) +
    ggplot2::geom_violin(draw_quantiles = c(0.5), bw = 0.1)


Answered By - bers
Answer Checked By - Timothy Miller (PHPFixing Admin)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing