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.