Saltar al contenido

Agregar marcas de graduación menores al eje x en ggplot2 (sin etiquetas)

Esta es la contestación más exacta que encomtrarás aportar, pero obsérvala pausadamente y analiza si se puede adaptar a tu trabajo.

Solución:

Esto lo haría en el caso preciso:

scale_x_continuous(breaks= seq(1900,2000,by=10), 
                  labels = c(1900, rep("",4), 1950, rep("",4), 2000), 
                  limits = c(1900,2000), expand = c(0,0)) +

Aquí hay una función que no es a prueba de balas pero que funciona para insertar etiquetas en blanco cuando las etiquetas principales iniciales y finales están alineadas con los valores de inicio y finalización de la at argumento:

insert_minor <- function(major_labs, n_minor) labs <- 
                              c( sapply( major_labs, function(x) c(x, rep("", 4) ) ) )
                              labs[1:(length(labs)-n_minor)]

Prueba:

p <- ggplot(df, aes(x=x, y=y))
  p + geom_line() + 
  scale_x_continuous(breaks= seq(1900,2000,by=10), 
                     labels = insert_minor( seq(1900, 2000, by=50), 4 ), 
                     limits = c(1900,2000), expand = c(0,0)) +
  scale_y_continuous(breaks = c(20,40,60,80), limits = c(0,100)) +
  theme(legend.position="none", panel.background = element_blank(), 
        axis.line = element_line(color='black'), panel.grid.minor = element_blank())

Aunque la respuesta anterior puede agregar descansos, estos no son realmente los minor_breaks. Para hacerlo, puede usar annotation_ticks función, que funciona de manera similar a annotation_logticks.

La función de código está disponible aquí. Puede que necesite cargar grid paquete

annotation_ticks <- function(sides = "b",
                             scale = "identity",
                             scaled = TRUE,
                             short = unit(0.1, "cm"),
                             mid = unit(0.2, "cm"),
                             long = unit(0.3, "cm"),
                             colour = "black",
                             size = 0.5,
                             linetype = 1,
                             alpha = 1,
                             color = NULL,
                             ticks_per_base = NULL,
                             ...) 
  if (!is.null(color)) 
    colour <- color
  

  # check for invalid side
  if (grepl("[^btlr]", sides)) 
    stop(gsub("[btlr]", "", sides), " is not a valid side: b,t,l,r are valid")
  

  # split sides to character vector
  sides <- strsplit(sides, "")[[1]]

  if (length(sides) != length(scale)) 
    if (length(scale) == 1) 
      scale <- rep(scale, length(sides))
     else 
      stop("Number of scales does not match the number of sides")
    
  

  base <- sapply(scale, function(x) switch(x, "identity" = 10, "log10" = 10, "log" = exp(1)), USE.NAMES = FALSE)

  if (missing(ticks_per_base)) 
    ticks_per_base <- base - 1
   else 
    if ((length(sides) != length(ticks_per_base))) 
      if (length(ticks_per_base) == 1) 
        ticks_per_base <- rep(ticks_per_base, length(sides))
       else 
        stop("Number of ticks_per_base does not match the number of sides")
      
    
  

  delog <- scale %in% "identity"

  layer(
    data = data.frame(x = NA),
    mapping = NULL,
    stat = StatIdentity,
    geom = GeomTicks,
    position = PositionIdentity,
    show.legend = FALSE,
    inherit.aes = FALSE,
    params = list(
      base = base,
      sides = sides,
      scaled = scaled,
      short = short,
      mid = mid,
      long = long,
      colour = colour,
      size = size,
      linetype = linetype,
      alpha = alpha,
      ticks_per_base = ticks_per_base,
      delog = delog,
      ...
    )
  )


#' Base ggproto classes for ggplot2
#'
#' If you are creating a new geom, stat, position, or scale in another package,
#' you'll need to extend from ggplot2::Geom, ggplot2::Stat, ggplot2::Position, or ggplot2::Scale.
#'
#' @seealso codelink[ggplot2]ggplot2-ggproto
#' @usage NULL
#' @format NULL
#' @rdname ggplot2-ggproto
#' @export
GeomTicks <- ggproto(
  "GeomTicks", Geom,
  extra_params = "",
  handle_na = function(data, params) 
    data
  ,

  draw_panel = function(data,
                        panel_scales,
                        coord,
                        base = c(10, 10),
                        sides = c("b", "l"),
                        scaled = TRUE,
                        short = unit(0.1, "cm"),
                        mid = unit(0.2, "cm"),
                        long = unit(0.3, "cm"),
                        ticks_per_base = base - 1,
                        delog = c(x = TRUE, y = TRUE)) 
    ticks <- list()

    # Convert these units to numbers so that they can be put in data frames
    short <- convertUnit(short, "cm", valueOnly = TRUE)
    mid <- convertUnit(mid, "cm", valueOnly = TRUE)
    long <- convertUnit(long, "cm", valueOnly = TRUE)

    for (s in 1:length(sides)) 
      if (grepl("[b
    gTree(children = do.call("gList", ticks))
  ,
  default_aes = aes(colour = "black", size = 0.5, linetype = 1, alpha = 1)
)


# Calculate the position of log tick marks Returns data frame with: - value: the
# position of the log tick on the data axis, for example 1, 2, ..., 9, 10, 20, ...
# - start: on the other axis, start position of the line (usually 0) - end: on the
# other axis, end position of the line (for example, .1, .2, or .3)
calc_ticks <- function(base = 10,
                       ticks_per_base = base - 1,
                       minpow = 0,
                       maxpow = minpow + 1,
                       majorTicks = 0,
                       start = 0,
                       shortend = 0.1,
                       midend = 0.2,
                       longend = 0.3,
                       delog = FALSE) 

  # Number of blocks of tick marks
  reps <- maxpow - minpow

  # For base 10: 1, 2, 3, ..., 7, 8, 9, 1, 2, ...
  ticknums <- rep(seq(1, base - 1, length.out = ticks_per_base), reps)

  # For base 10: 1, 1, 1, ..., 1, 1, 1, 2, 2, ... (for example)
  powers <- rep(seq(minpow, maxpow - 1), each = ticks_per_base)

  ticks <- ticknums * base ^ powers

  ticks <- c(ticks, base ^ maxpow) # Add the last tick mark

  # Set all of the ticks short
  tickend <- rep(shortend, length(ticks))

  # Get the position within each cycle, 0, 1, 2, ..., 8, 0, 1, 2. ...
  cycleIdx <- ticknums - 1

  # Set the 'major' ticks long
  tickend[cycleIdx == 0] <- longend

  # Where to place the longer tick marks that are between each base For base 10, this
  # will be at each 5
  longtick_after_base <- floor(ticks_per_base / 2)
  tickend[cycleIdx == longtick_after_base] <- midend

  if (delog) 
    ticksCopy <- ticks

    regScale <- log(ticks, base)

    majorTicks <- sort(
      unique(
        c(
          minpow,
          regScale[which(regScale %in% majorTicks)],
          maxpow,
          majorTicks
        )
      )
    )

    expandScale <- c()

    if (length(majorTicks) > 1) 
      for (i in 1:(length(majorTicks) - 1)) 
        expandScale <- c(
          expandScale,
          seq(majorTicks[i], majorTicks[i + 1], length.out = (ticks_per_base + 1))
        )
      

      ticks <- unique(expandScale)

      # Set all of the ticks short
      tickend <- rep(shortend, length(ticks))

      # Set the 'major' ticks long
      tickend[which(ticks %in% majorTicks)] <- longend
    
  

  tickdf <- data.frame(value = ticks, start = start, end = tickend)

  tickdf

Muy buenas funciones arriba.

Una solución que encuentro algo más simple o más fácil de entender es simplemente especificar sus rupturas de eje mayor en los incrementos que desea tanto para rupturas mayores como menores, por lo que si desea mayores en incrementos de 10 y menores en incrementos de 5, no obstante, debe especificar sus incrementos principales en pasos de 5.

Luego, en el tema, se le pide que le dé un color al texto del eje. En lugar de elegir uno color, puedes darle un lista de colores: especificando el color que desee que sea el número del eje mayor, y luego NA para el color del eje menor. Esto le dará el texto en la marca principal, pero nada en la marca 'menor'. Del mismo modo, para la cuadrícula que va dentro de la gráfica, puede especificar una lista para los tamaños de línea, de modo que todavía haya una diferencia de grosor para las líneas de cuadrícula mayores y menores dentro de la gráfica, aunque esté especificando las líneas de cuadrícula menores como cuadrícula mayor. líneas. Como ejemplo de lo que podría poner en el tema:

panel.grid.major.x = element_line(colour = c("white"), size = c(0.33, 0.2)),
panel.grid.major.y = element_line(colour = c("white"), size = c(0.33, 0.2)),
axis.text.y = element_text(colour = c("black", NA), family = "Gill Sans"),
axis.text.x = element_text(colour = c("black", NA), family = "Gill Sans"),

Sospecho que puede cambiar el tamaño de la marca de verificación exterior exactamente de la misma manera, aunque no lo he probado.

Si para ti ha sido provechoso este artículo, agradeceríamos que lo compartas con más desarrolladores de este modo nos ayudas a dar difusión a nuestro contenido.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)


Tags : / /

Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *