如何使用 ggplot2 获取此图中的轴刻度和刻度?

How to get axis scale and ticks in this plot using ggplot2?

我正在尝试使用 ggplot2 制作经典的 Von Neumann Morgenstern 凹效用函数图,但在获取图中的轴刻度时遇到了一些问题。

这是我的完整代码。不需要数据集。


library(ggplot2)
library(tidyverse)
library(hrbrthemes)
library(ggforce)


utility2 = function(c, A){
  ret = ((c^(1-A))/(1-A))
}

risk_grid <- 1:20/10

risk_aversion = 1.2

return2 = utility2(risk_grid, risk_aversion)
return2 <- as.data.frame(return2)
return2 <- cbind(return2, risk_grid)


name <- data.frame(c(0.165,1.512, 0.77), c(-6.92, -4.5, -5.17))
points <- data.frame(c(0.188,1.512, 0.8, 0.8), c(-7, -4.6, -5.88, -5.23))
line <- data.frame(c(.188, 1.512),c(-7, -4.6))
line2 <- data.frame(c(0.8, 0.8), c(-5.88, -5.23))
axis_lineA <- data.frame(c(0.188,0.188,0.1), c(-7, -Inf, -7))
axis_lineB <- data.frame(c(1.512, 1.512, 0.1), c(-4.6, -Inf, -4.6))
axis_lineC <- data.frame(c(0.8, 0.8, 0.1), c(-5.23, -Inf, -5.23))
axis_lineD <- data.frame(c(0.8, 0.1), c(-5.88, -5.88))
ticks <- data.frame(c(0.188,1.512), c(-7.5, -7))

colnames(name) <- c("x", "y")
colnames(points) <- c("x", "y")
colnames(line) <- c("x", "y")
colnames(line2) <- c("x", "y")
colnames(axis_lineA) <- c("x", "y")
colnames(axis_lineB) <- c("x", "y")
colnames(axis_lineC) <- c("x", "y")
colnames(axis_lineD) <- c("x", "y")
colnames(ticks) <- c("x", "y")

jpeg(file = "Utility_plot.jpeg", width = 800, height = 800)


P_Utility <- ggplot()+
  geom_line(data = return2, aes(x=risk_grid, y = return2), size = 1, color = "steelblue")+
  #scale_x_continuous(breaks = return2$risk_grid, labels = return2$risk_grid) +
  geom_text(data = name, aes(x=x, y = y), label = c("a", "b", "c"), size = 7, family = "serif")+
  geom_line(data = line, aes(x=x, y = y), size = .5, color = "black")+
  geom_line(data = line2, aes(x=x, y = y), size = 1, color = "grey", linetype = "dashed")+
  geom_line(data = axis_lineA, aes(x=x, y = y), size = 1, color = "grey", linetype = "dashed")+
  geom_line(data = axis_lineB, aes(x=x, y = y), size = 1, color = "grey", linetype = "dashed")+
  geom_line(data = axis_lineC, aes(x=x, y = y), size = 1, color = "grey", linetype = "dashed")+
  geom_line(data = axis_lineD, aes(x=x, y = y), size = 1, color = "grey", linetype = "dashed")+
  geom_point(data = points, aes(x=x, y = y), size = 4, color = "red")+
  #geom_point(data = ticks, aes(x=x, y = y), size = 4, color = "red")+
  theme_ipsum()+
  #theme(legend.text = element_text(size = 12))+
  #theme(legend.title = element_blank())+
  #theme(axis.ticks=element_line(size = 2))+
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank())+
  theme(axis.text.x = element_blank()) +
  theme(axis.text.y = element_blank())+
  scale_x_continuous(expand = c(0,0))+
  xlab("c") + ylab("u(c)")+
  theme(axis.title.y = element_text(size = 20, vjust = .5, angle = 0, family = "serif"),
        axis.title.x = element_text(size = 20, hjust = .5, family = "serif"))+
  theme(axis.line = element_line(arrow = arrow(length = unit(3, 'mm'))))+
  theme(text=element_text(family="serif"))
P_Utility

dev.off()

该代码可能不是最佳的,但到目前为止它可以工作。我对情节很满意,但希望在虚线穿过 x 轴和 y 轴的地方有刻度和标签。

这可以这样实现:

  1. 将轴的中断设置为来自 dfs 行的唯一 x 和 y 值
  2. 要获得您必须设置 axis.ticks.x/y = element_line()。使用 axis.ticks 将无法完成工作,因为 theme_ipsum axis.ticks.x/y 都设置为 element_blank()
library(ggplot2)
library(tidyverse)
library(hrbrthemes)
library(ggforce)


utility2 = function(c, A){
  ret = ((c^(1-A))/(1-A))
}

risk_grid <- 1:20/10

risk_aversion = 1.2

return2 = utility2(risk_grid, risk_aversion)
return2 <- as.data.frame(return2)
return2 <- cbind(return2, risk_grid)


name <- data.frame(c(0.165,1.512, 0.77), c(-6.92, -4.5, -5.17))
points <- data.frame(c(0.188,1.512, 0.8, 0.8), c(-7, -4.6, -5.88, -5.23))
line <- data.frame(c(.188, 1.512),c(-7, -4.6))
line2 <- data.frame(c(0.8, 0.8), c(-5.88, -5.23))
axis_lineA <- data.frame(c(0.188,0.188,0.1), c(-7, -Inf, -7))
axis_lineB <- data.frame(c(1.512, 1.512, 0.1), c(-4.6, -Inf, -4.6))
axis_lineC <- data.frame(c(0.8, 0.8, 0.1), c(-5.23, -Inf, -5.23))
axis_lineD <- data.frame(c(0.8, 0.1), c(-5.88, -5.88))
ticks <- data.frame(c(0.188,1.512), c(-7.5, -7))

colnames(name) <- c("x", "y")
colnames(points) <- c("x", "y")
colnames(line) <- c("x", "y")
colnames(line2) <- c("x", "y")
colnames(axis_lineA) <- c("x", "y")
colnames(axis_lineB) <- c("x", "y")
colnames(axis_lineC) <- c("x", "y")
colnames(axis_lineD) <- c("x", "y")
colnames(ticks) <- c("x", "y")

breaks_x <- unique(c(axis_lineA$x, axis_lineB$x, axis_lineC$x, axis_lineD$x))
breaks_y <- unique(c(axis_lineA$y, axis_lineB$y, axis_lineC$y, axis_lineD$y))
ggplot()+
  geom_line(data = return2, aes(x=risk_grid, y = return2), size = 1, color = "steelblue")+
  geom_text(data = name, aes(x=x, y = y), label = c("a", "b", "c"), size = 7, family = "serif")+
  geom_line(data = line, aes(x=x, y = y), size = .5, color = "black")+
  geom_line(data = line2, aes(x=x, y = y), size = 1, color = "grey", linetype = "dashed")+
  geom_line(data = axis_lineA, aes(x=x, y = y), size = 1, color = "grey", linetype = "dashed")+
  geom_line(data = axis_lineB, aes(x=x, y = y), size = 1, color = "grey", linetype = "dashed")+
  geom_line(data = axis_lineC, aes(x=x, y = y), size = 1, color = "grey", linetype = "dashed")+
  geom_line(data = axis_lineD, aes(x=x, y = y), size = 1, color = "grey", linetype = "dashed")+
  geom_point(data = points, aes(x=x, y = y), size = 4, color = "red") +
  scale_x_continuous(breaks = breaks_x, expand = c(0,0))+
  scale_y_continuous(breaks = breaks_y, expand = c(0,0))+
  theme_ipsum() +
  theme(panel.grid.major = element_blank(), 
        panel.grid.minor = element_blank(),
        axis.ticks.x = element_line(),
        axis.ticks.y = element_line(),
        axis.ticks.length = unit(5, "pt")) +
  theme(axis.text.x = element_blank()) +
  theme(axis.text.y = element_blank())+
  
  xlab("c") + ylab("u(c)")+
  theme(axis.title.y = element_text(size = 20, vjust = .5, angle = 0, family = "serif"),
        axis.title.x = element_text(size = 20, hjust = .5, family = "serif"))+
  theme(axis.line = element_line(arrow = arrow(length = unit(3, 'mm'))))+
  theme(text=element_text(family="serif"))