Closed bklingen closed 2 years ago
Hi,
Offset seems to be a percentage between min & max values of the data not the axis, so here [-3.5, 3.5]
not [-4, 4]
, so you can do something like this to find the percentage you want:
scales::rescale(-2.58, from = c(-3.5, 3.5), to = c(0, 100))
If you use fill, you have a duplicate a point to connect the two series, something like this:
x <- seq(-3.5,3.5, length.out = 100)
df <- data.frame(x = x, y = dnorm(x), z=1)
df$z[df$x > qnorm(0.025)] <- 2
df <- rbind(
df,
transform(df[df$z == 1, ][which.max(df[df$z == 1, "x"]), ], z = 2)
)
apex(
data=df,
mapping=aes(x=x, y=y, fill=z),
type='area-spline'
) %>%
ax_xaxis(type='numeric') %>%
ax_fill(type="solid", colors=c("#FFFF00","#FF9900"))
Victor
Wonderful, thank you very much! The solution with mapping the offset to the data series works fine. Just for completeness, here is how to shade 100*alpha percent of the area:
library(apexcharter)
alpha <- 0.025
x <- seq(-3.5,3.5,0.01)
df <- data.frame(x=x, y=dnorm(x))
myoffset <- (qnorm(alpha) - min(x))/diff(range(x)) * 100
if(myoffset<0) myoffset <- 0
if(myoffset>100) myoffset <- 100
apex(
data = df,
mapping = aes(x=x, y=y),
type = 'area-spline'
) %>%
ax_xaxis(
type = 'numeric',
min = -4,
max = 4,
tickAmount = 8
) %>%
ax_fill(
type='gradient',
gradient=list(
type='horizontal',
opacityFrom=1,
opacityTo=1,
colorStops = list(
list(offset=myoffset, color="#FFFF00"), #yellow
list(offset=0, color="#FF9900") #orange
)
)
)
Regarding using the fill/color aesthetic: The duplication of the datapoint works great. When using splines, it is better to re-order the data after appending the duplicate data point at the end. However, one issue remains. When defining type='numerical'
in ax_xaxis
, the x-axis tick marks seemed to get messed up. Here is an example just adding a second series:
## using color aesthetics
alpha <- 0.025
x <- seq(-3.5,3.5,0.01)
df <- data.frame(x=x, y=dnorm(x), z=1)
df$z[df$x>qnorm(alpha)] <- 2
##duplicate data point where two curves meet and sort the dataframe:
df <- rbind(
df,
transform(df[df$z == 1, ][which.max(df[df$z == 1, "x"]), ], z = 2)
)
df <- df[order(df$z, df$x),]
## add second series:
apex(
data = df[df$z==1,],
mapping = aes(x=x, y=y),
type = 'line'
) %>%
add_line(
data = df[df$z==2,],
mapping = aes(x=x, y=y),
type = 'line'
) %>%
ax_xaxis(
type = 'numeric',
labels = list(
formatter = htmlwidgets::JS("function(value) {return value.toFixed(2);}")
)
)
Without the entire ax_xaxis
statement, the axis looks a bit messy (but seems to be correct):
I tried a toy example, and there using type='numerical'
in ax_xaxis
seems to work just fine:
## toy example
df <- data.frame(x=c(1,2,3,3,4,5,6), y=c(1,2,3,3,3,1,2), z=c(1,1,1,2,2,2,2))
## add second series:
apex(
data = df[df$z==1,],
mapping = aes(x=x, y=y),
type = 'line'
) %>%
add_line(
data = df[df$z==2,],
mapping = aes(x=x, y=y),
type = 'line'
) %>%
ax_xaxis(type="numeric")
In this toy example, the ax_xaxis(type="numeric")
is essential. Without it, one gets:
Supposing I'm trying to shade the 10% lower tail in a normal distribution. I though I could do that using
type=area-spline
and specifying appropriate stops in the color gradient inax_fill
. When shading exactly 50% of the distribution, this seems to work, usingoffset=50
:But how do I shade the lower 10%? Using
list(offset=10, color="#FFFF00"), #yellow
does shade a smaller portion, but it doesn't correspond to 10% of the area. What is the relationship between the offset and the area that is colored? Probably something much simpler than I'm imagining. Finally, what if I want to shade three areas, i.e., the lower 10%, the middle 70%, and the upper 20%?In a different vein, I also tried this approach using a
fill
aesthetic (I was unsuccessful usingfillColor
):This is close enough (although there is a white space), but in fact the x-axis got messed up (the graph is now centered at 1)! There is a warning to use
complete
, but using it as indf <- complete(df, x, z)
didn't help either. I must be doing something wrong.