问题
I am intrigued by this plot of Albert Cairo.
I can smooth my curve sufficiently with ggforce::bspline
However, now that I don't have a date axis I am unsure as to how to change the color of a spline midway.
Let's assume that the three points represent the years 1990, 1991 and 1992. And someone got elected on July 1, 1990. I would like to change the color of the spline at this point. So the curved line would be red from origin until aprox (12, 5.6) then blue from (12, 5.6) to (17,4)
I am not sure how to accomplish this.
library(ggforce)
library(ggplot2)
data <- tibble (
x = c(10, 15, 17),
y = c(5, 7, 4)
)
ggplot(data) +
stat_bspline2(aes(x = x, y = y), n = 300, geom = "bspline0", color = "red") +
stat_bspline2(aes(x = x, y = y), n = 3, geom = "point", color = "red") +
geom_point(aes(x = x, y = y), color = "grey")
Thinking about what M.A. told me about groups I now have code that can:
Change the color of straight line segments:
# Works for straight lines
ggplot(data, aes(x=x, y=y, colour = g, group = 1)) +
geom_line(size = 3) +
geom_point() +
scale_color_manual(values = c("A" = "red", "B" = "pink", "C" = "green", "D" = "white"))
And the continuous colour of a bspline. But I would like this to be discrete colors only as in the plot above.
# Works with continuous color
ggplot(data, aes(x=x, y=y, colour = g, group = 1)) +
geom_bspline2(size = 4, n = 300) +
scale_color_manual(values = c("A" = "red", "B" = "pink", "C" = "green", "D" = "white"))
Or this error, "Error: Continuous value supplied to discrete scale" with:
ggplot(data) +
stat_bspline2(aes(x = x, y = y, color = ..group.., group = 1), n = 300, geom = "bspline0") +
scale_color_manual(values = c("A" = "red", "B" = "pink", "C" = "green", "D" = "white"))
So I'm wondering how to manually control the color of discrete segments with bspline.
回答1:
You can do this by grouping:
data <- tibble (
x = c(10, 15, 17, 17, 20, 22),
y = c(5, 7, 4, 4, 0, 5),
g = c("A", "A", "A", "B", "B", "B")
)
ggplot(data) +
stat_bspline2(
aes(x = x, y = y, color = ..group.., group = g),
n = 300, geom = "bspline0") +
scale_colour_gradient(low = "blue", high = "red", guide=FALSE)
Edit:
The error Continuous value supplied to discrete scale
is is somewhat confusing here. I don't know if there is an easier way to get what you want but it can be achieved using scale_colour_gradientn()
. This function allows to map the group g
to a gradient between n
colours so you want n
to be the number of groups.
For example, consider a larger data set with four groups:
# example data
data <- tibble (
x = c(10, 15, 17, 17, 20, 22, 22, 23, 25, 25, 27, 29),
y = c(5, 7, 4, 4, 0, 5, 5, 6, 5, 5, 4, 5.5),
g = c("A", "A", "A", "B", "B", "B", "C", "C", "C", "D","D","D")
)
You can use a palette like rainbow()
and specify the number of colours for the gradient to be 4 since there are four groups A
, B
, C
and D
.
# use a colour palette:
ggplot(data) +
stat_bspline2(
aes(x = x, y = y, color = ..group.., group = g),
n = 300, size = 1, geom = "bspline0") +
scale_color_gradientn(colours = rainbow(4),
guide = F
)
For custom colours, you may do the following:
# use custom colors:
ggplot(data, aes(x=x, y=y, color = ..group.., group = g)) +
geom_bspline2(size = 1, n = 300) +
scale_color_gradientn(
colours = c("red", "pink", "green", "white"),
guide = F
)
This uses a gradient between the colours red
, pink
, green
and white
. Note that the order of the colours matters as a different order leads to a different gradient and thus a different mapping of the groups.
来源:https://stackoverflow.com/questions/49739450/chop-up-bsplines-and-color-them