我想画一个区域,但是我不知道该怎么做

时间:2018-08-16 03:53:19

标签: r ggplot2 plot

my plot

我的意思是,我只想绘制正方形区域P1 X(Q1-Q2)。

不是梯形(P2 + P1)X(Q1-Q2 / 2)。

这是我使用的代码。我使用了ggplotdplyr。我该如何解决这个问题?

如何绘制唯一的方形区域而不是梯形区域!

library(ggplot2)
library(dplyr)
supply <- Hmisc::bezier(x = c(1, 8, 9),
                        y = c(1, 5, 9)) %>%
  as_data_frame()

demand <- Hmisc::bezier(c(1, 3, 9),
                        c(9, 3, 1)) %>%
  as_data_frame()


fun_supply <- approxfun(supply$x, supply$y, rule = 2)

fun_supply(c(2, 6, 8))
fun_demand <- approxfun(demand$x, demand$y, rule = 2)

intersection_funs <-  uniroot(function(x) fun_supply(x) - fun_demand(x), c(1, 9))
intersection_funs


y_root <- fun_demand(intersection_funs$root)


curve_intersect <- function(curve1, curve2) {
  # Approximate the functional form of both curves
  curve1_f <- approxfun(curve1$x, curve1$y, rule = 2)
  curve2_f <- approxfun(curve2$x, curve2$y, rule = 2)

  # Calculate the intersection of curve 1 and curve 2 along the x-axis
  point_x <- uniroot(function(x) curve1_f(x) - curve2_f(x), 
                     c(min(curve1$x), max(curve1$x)))$root

  # Find where point_x is in curve 2
  point_y <- curve2_f(point_x)

  # Finish 
  return(list(x = point_x, y = point_y))
}

intersection_xy <- curve_intersect(supply, demand)
intersection_xy
intersection_xy_df <- intersection_xy %>% as_data_frame()


demand2 <- Hmisc::bezier(c(1.5, 3.5, 9.5),
                         c(9.5, 3.5, 1.5)) %>%
  as_data_frame()

supply2 <- Hmisc::bezier(c(1,7,8),
                         c(3,7,11)) %>%
  as_data_frame()
#Make a data frame of the intersections of the supply curve and both demand curves

intersections <- bind_rows(curve_intersect(supply, demand),
                           curve_intersect(supply2, demand2))

plot_labels <- data_frame(label = c("S", "D","S[1]","D[1]"),
                          x = c(9, 1, 6.5, 3),
                          y = c(8, 8, 8, 8))



ggplot(mapping = aes(x = x, y = y)) + 
  geom_path(data = supply, color = "#0073D9", size = 1, linetype = "dashed") + 
  geom_path(data = demand, color = "#FF4036", size = 1, linetype = "dashed") + 
  geom_path(data = demand2, color = "#FF4036", size = 1) + 
  geom_path(data = supply2, color = "#0073D9", size = 1) +
  geom_segment(data = intersections, 
               aes(x = x, y = 0, xend = x, yend = y), lty = "dotted") +
  geom_segment(data = intersections, 
               aes(x = 0, y = y, xend = x, yend = y), lty = "dotted") + 
  geom_segment(data = intersections,
               aes(x = x, y = y, xend = x, yend=  y), lty = "dotted") +
  geom_point(data = intersections, size = 3) +
  geom_text(data = plot_labels,
            aes(x = x, y = y, label = label), parse = TRUE) +
  scale_x_continuous(expand = c(0, 0), breaks = intersections$x,
                     labels = expression(Q[1], Q[2])) +
  scale_y_continuous(expand = c(0, 0), breaks = intersections$y,
                     labels = expression(P[1], P[2]))+
  labs(x = "Quantity", y = "Price") +
  geom_area(data =intersections, fill="#9999FF", alpha=0.5) +
  theme_classic() + 
  coord_equal()

您能帮我画一下我提到的区域吗?

2 个答案:

答案 0 :(得分:6)

您可以尝试将geom_rect(data=intersections[1,], aes(xmin=0, xmax=x, ymin=0, ymax=y),fill='green', alpha=0.5)添加到绘图调用中。

所以我们有:

ggplot(mapping = aes(x = x, y = y)) + 
  geom_path(data = supply, color = "#0073D9", size = 1, linetype = "dashed") + 
  geom_path(data = demand, color = "#FF4036", size = 1, linetype = "dashed") + 
  geom_path(data = demand2, color = "#FF4036", size = 1) + 
  geom_path(data = supply2, color = "#0073D9", size = 1) +
  geom_segment(data = intersections, 
               aes(x = x, y = 0, xend = x, yend = y), lty = "dotted") +
  geom_segment(data = intersections, 
               aes(x = 0, y = y, xend = x, yend = y), lty = "dotted") + 
  geom_segment(data = intersections,
               aes(x = x, y = y, xend = x, yend=  y), lty = "dotted") +
  geom_point(data = intersections, size = 3) +
  geom_text(data = plot_labels,
            aes(x = x, y = y, label = label), parse = TRUE) +
  scale_x_continuous(expand = c(0, 0), breaks = intersections$x,
                     labels = expression(Q[1], Q[2])) +
  scale_y_continuous(expand = c(0, 0), breaks = intersections$y,
                     labels = expression(P[1], P[2]))+
  labs(x = "Quantity", y = "Price") +
  geom_area(data =intersections, fill="#9999FF", alpha=0.5) +
  theme_classic() + 
  coord_equal()+
  geom_rect(data=intersections[1,], aes(xmin=0, xmax=x, ymin=0, ymax=y),fill='green', alpha=0.5)

enter image description here

根据评论进行编辑:

geom_rect(data=intersections, aes(xmin=x[2], xmax=x[1], ymin=0, ymax=y[1]),fill='green', alpha=0.5)

enter image description here

答案 1 :(得分:1)

尽管J Con的答案很深入,并且确实提供了解决方案,但ggplot2中更干净的方法可能是使用annotate函数,并适当设置geom和其他参数。 (请参阅帮助页面链接。)

这是因为使用geom_rect之类的东西涉及传递位置等作为data.frame,从图形语法,数据层和注释层是不同的:以系统和客观的方式将数据变量映射到图形美感,以及以零星的和主观的方式在数据集中标记特征的行为是单独的活动,并且明确地将annotate用于后一个目的在代码和概念方面使这种划分更加清晰。

编辑

更具体地说,annotate等同于以下内容:

geom_rect(data=intersections, aes(xmin=x[2], xmax=x[1], ymin=0, ymax=y[1]),fill='green', alpha=0.5)

可能会如下

annotate(
   geom = "rect",
   xmin = intersections$x[2], x = intersections$x[1],
   ymin = 0, ymax = intersections$y[1],
   fill = 'green', alpha = 0.5
)

从功能上讲,这是完全相同的,但是从概念上讲,它使所表达的代码中的数据层和注释层之间的分隔更加清晰。

注意:注解也可以用于标记点和文本。