ichimomo / frasyr

Fisheries Research Agency (FRA) provides the method for calculating sustainable yield (SY) with R
https://ichimomo.github.io/frasyr/
GNU General Public License v3.0
16 stars 21 forks source link

ファセット形式グラフの任意パネルの軸をズームする方法 #637

Open JK-junkin opened 3 years ago

JK-junkin commented 3 years ago

問題 frasyrに限らず、ggplot2:package:のfacet_wrap()等を使って図を描いた後で、任意のパネル (= facet) の縦軸表示範囲を調整したいことがあります。例えばwikiのここで、fishing_mortalityパネルの低い値にズームインしたい場合などです。

対応案 このサイトを参考にして、coord_panel_ranges()関数を自作して、frasyrの出力結果に下記のように追記すると調整できました。

# 任意facetの縦軸調整
res_vpa_retrospective$graph +
    coord_panel_ranges(panel_ranges = list(
                              list(NULL),
                              list(NULL),
                              list(y = c(0, 5)), # 調整したいパネルごとにy軸の範囲を指定
                              list(NULL),
                              list(NULL))) 
JK-junkin commented 3 years ago

上記の参考サイト (https://andburch.github.io/ggplot_facets/) にあるコードのままではエラーが出たので、私はエラーを起こした箇所をコメントアウトして使っています。下記に載せておきます。

UniquePanelCoords <- ggplot2::ggproto(
  "UniquePanelCoords", ggplot2::CoordCartesian,

  num_of_panels = 1,
  panel_counter = 1,
  panel_ranges = NULL,

  setup_layout = function(self, layout, params) {
    self$num_of_panels <- length(unique(layout$PANEL))
    self$panel_counter <- 1
    layout
  },

  setup_panel_params =  function(self, scale_x, scale_y, params = list()) {
    if (!is.null(self$panel_ranges) & length(self$panel_ranges) != self$num_of_panels)
      stop("Number of panel ranges does not equal the number supplied")

    train_cartesian <- function(scale, limits, name, given_range = NULL) {
      if (is.null(given_range)) {
#         range <- ggplot2:::scale_range(scale, limits, self$expand)
          expansion <- ggplot2:::default_expansion(scale, expand = self$expand)
          range <- ggplot2:::expand_limits_scale(scale, expansion,
                                                 coord_limits = self$limits[[name]])
      } else {
          range <- given_range
      }

#       out <- scale$break_info(range)
#       out$arrange <- scale$axis_order()
#       names(out) <- paste(name, names(out), sep = ".")
#       out
      out <- list(
        ggplot2:::view_scale_primary(scale, limits, range),
        sec = ggplot2:::view_scale_secondary(scale, limits, range),
        arrange = scale$axis_order(),
        range = range
    )
    names(out) <- c(name, paste0(name, ".", names(out)[-1]))
    out
    }

    cur_panel_ranges <- self$panel_ranges[[self$panel_counter]]
    if (self$panel_counter < self$num_of_panels)
      self$panel_counter <- self$panel_counter + 1
    else
      self$panel_counter <- 1

    c(train_cartesian(scale_x, self$limits$x, "x", cur_panel_ranges$x),
      train_cartesian(scale_y, self$limits$y, "y", cur_panel_ranges$y))
  }
)

coord_panel_ranges <- function(panel_ranges, expand = TRUE,
                               default = FALSE, clip = "on") {
    ggplot2::ggproto(NULL, UniquePanelCoords, panel_ranges = panel_ranges,
                     expand = expand, default = default, clip = clip)
}
JK-junkin commented 3 years ago

この関数を適当なスクリプトファイル (たとえばcoord_facet.r) にして、 source("coord_facet.r", encoding = "UTF-8") と読み込んで使っています。

JK-junkin commented 1 year ago
ichimomo commented 1 year ago

この方法(facet形式の図ごとに任意の縦軸の上限・下限を与える)をずっと探してました!ありがとうございます.