Partially smooth the line graph with geom_xspline()

140 Views Asked by At

I have the following data:

> dput(material)
structure(list(strain = c(-0.00496, -0.00375, -0.00248, -0.00195, 
-0.00121, -0.000248, 0, 0.000132, 0.00145, -0.0058846, -0.0046736, 
-0.0034036, -0.0028676, -0.0021336, -0.0011707, -0.0009226, 0, 
1e-15), stress = c(-4, -4.6011, -5, -4.8555, -3.9414, -0.9901, 
0, 0.5303, 0, -4, -4.6011, -5, -4.8555, -3.9414, -0.9901, 0, 
0, 0), type = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("Standard 5 ksi Concrete", 
"Adjusted 5 ksi Concrete"), class = "factor")), row.names = c(NA, 
-18L), class = "data.frame")

I plot the data as:

library(ggplot2)
library(ggalt)
plot <- ggplot(material) + theme_void() + scale_color_hue() +
 aes(x = strain, y = stress, colour = type, group = type) +
 geom_xspline(size = 0.7, spline_shape = 0.5) + labs(x = "Strain (in/in)", 
 y = "Stress (ksi)", color = element_blank()) + theme(legend.position = "bottom", 
   legend.box.background = element_rect(colour = "black", size = 0.5),
   axis.title.y = element_text(margin = margin(0,25,0,0), size=12, colour="black", angle = 90),
   axis.title.x = element_text(margin = margin(20,0,20,0),size=12, colour="black"),
   axis.text.y = element_blank(), axis.text.x = element_blank(),
   legend.text=element_text(size=11, margin = margin(0,2,0,0))) + 
  scale_y_continuous(trans = "reverse") + scale_x_continuous(trans = "reverse") + 
  geom_vline(aes(xintercept = 0), size = 0.3) +
  geom_hline(aes(yintercept = 0), size = 0.3)

The resultant graph is drawn below. But I want to keep one part of the graph flat (do not smooth with spline_shape) this is shown in the thick purple line. How can I edit the code to keep that one part of the data plate? In other words, I was to plot the true coordinate for that one single datapoint.

enter image description here

1

There are 1 best solutions below

0
On

I ended up doing it manually by adding a geom_line and editing the original data, still looking for a systematic solution though!

The new data is:

> dput(material)
structure(list(strain = c(-0.00496, -0.00375, -0.00248, -0.00195, 
-0.00121, -0.000248, 0, 0.000132, 0.00145, -0.0058846, -0.0046736, 
-0.0034036, -0.0028676, -0.0021336, -0.0011707, -0.0009226), 
stress = c(-4, -4.6011, -5, -4.8555, -3.9414, -0.9901, 0, 
0.5303, 0, -4, -4.6011, -5, -4.8555, -3.9414, -0.9901, 0), 
type = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L), .Label = c("Standard 5 ksi Concrete", 
"Adjusted 5 ksi Concrete"), class = "factor")), row.names = c(NA, 
-16L), class = "data.frame")

New code:

plot <- ggplot(material) + theme_void() + scale_color_hue() +
 aes(x = strain, y = stress, colour = type, group = type) +
 geom_xspline(size = 1, spline_shape = 0.5) + labs(x = "Strain (in/in)", 
 y = "Stress (ksi)", color = element_blank()) + theme(legend.position = "bottom", 
   legend.box.background = element_rect(colour = "black", size = 0.5),
   axis.title.y = element_text(size=20, colour="black", angle = 90, vjust = -22),
   axis.title.x = element_text(size=20, colour="black", vjust = 10, hjust = 0.6),
   axis.text.y = element_blank(), axis.text.x = element_blank(),
   legend.text=element_text(size=20, margin = margin(2,5,3,3))) + 
  scale_y_continuous(trans = "reverse") + scale_x_continuous(trans = "reverse") + 
  geom_vline(aes(xintercept = 0), size = 0.3) + geom_hline(aes(yintercept = 0), size = 0.3) + 
  geom_segment(aes(x = 0, y = 0, xend = -0.0009226, yend = 0), size = 1) +
  geom_segment(aes(x = -0.0009226, y = 0, xend = -0.0011707, yend = -0.94), size = 1)

The results looks like:

enter image description here