Chop up bsplines and color them

本秂侑毒 提交于 2019-12-11 16:24:16

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!