R Нарисуйте все метки осей (запретите некоторые из них пропустить)

Когда я вручную добавляю следующие метки с (axis(1, at=1:27, labels=labs[0:27])):

> labs[0:27]
 [1] "0\n9.3%"  "1\n7.6%"  "2\n5.6%"  "3\n5.1%"  "4\n5.7%"  "5\n6.5%"  "6\n7.3%"  "7\n7.6%"  "8\n7.5%"  "9\n7%"    "10\n6.2%" "11\n5.2%"
[13] "12\n4.2%" ........

Я получаю следующее:

enter image description here

Как заставить все ярлыки рисоваться так, чтобы 1,3,5,6 и 11 не были пропущены? (также, для дополнительного кредита, как мне переместить все на несколько пикселей?)

Ответ 1

? axis сообщает вам, что:

Код пытается не нарисовать перекрывающиеся метки меток, и поэтому опускает метки, где они будут упираться или перекрывать ранее нарисованные метки. Это может привести, например, к маркировке каждого другого тика. (Тики рисуются слева направо или снизу вверх, а между метками остается пробел, по крайней мере, размером "m".)

Играйте с cex.axis так, чтобы метки были достаточно малы, чтобы соответствовать без перекрытия

labs <-c("0\n9.3%","1\n7.6%","2\n5.6%","3\n5.1%","4\n5.7%","5\n6.5%","6\n7.3%",
         "7\n7.6%","8\n7.5%","9\n7%", "10\n6.2%","11\n5.2%","12\n4.2%",12:27)
plot(1:27,xaxt = "n")
axis(side=1, at=1:27, labels=labs[0:27],cex.axis=0.35)

Если вы расширяете график (вручную, перетаскивая или программно), вы можете увеличить размер ваших меток.

Ответ 2

Если вы действительно хотите, чтобы все метки отображались, даже если они очень близки или перекрываются, вы можете "обмануть" R, чтобы отобразить их, добавив метки нечетной и четной оси отдельными командами, как показано ниже:

labs <-c("0\n9.3%","1\n7.6%","2\n5.6%","3\n5.1%","4\n5.7%","5\n6.5%","6\n7.3%",
         "7\n7.6%","8\n7.5%","9\n7%", "10\n6.2%","11\n5.2%","12\n4.2%",13:27)
n=length(labs)
plot(1:28, xaxt = "n")
axis(side=1, at=seq(1,n,2), labels=labs[seq(1,n,2)], cex.axis=0.6)
axis(side=1, at=seq(2,n,2), labels=labs[seq(2,n,2)], cex.axis=0.6)

enter image description here

Вы можете поиграть с cex.axis, чтобы получить желаемый размер текста. Также обратите внимание, что вам может потребоваться настроить количество значений в at= и/или labels=, чтобы они были равны.

Я согласен с @PLapointe и @joran, что, как правило, лучше не вмешиваться в поведение R по умолчанию в отношении перекрытия. Тем не менее, у меня было несколько случаев, когда метки осей выглядели нормально, даже если они не были полностью разделены на "м-ширину", и я наткнулся на хитрость чередования нечетных и четных меток, чтобы получить поведение, которое я в розыске.

Ответ 3

@Papointe только что опубликовал то, что я собирался сказать, но опустил бонусный ответ.

Установите padj = 0.5 в axis, чтобы слегка переместить ярлыки.

Ответ 4

Несмотря на то, что здесь есть несколько хороших ответов, OP не захотела изменять размер ярлыков или что-либо менять об этом графике, кроме того, чтобы установить все метки осей. Это раздражает, так как часто кажется, что есть много места для размещения всех меток оси.

Здесь другое решение. Нарисуйте график без оси, затем добавьте тики с пустыми ярлыками. Сохраняйте позиции тиков в объекте, чтобы затем вы могли пройти каждый из них и поместить его в правильное положение на оси.

plot(1:10, 1:10, yaxt = "n") axis_ticks = axis(2, axTicks(2), labels = rep("", length(axTicks(2)))) for(i in axis_ticks) axis(2, i)

Ответ 5

У меня была аналогичная проблема, когда я хотел пошатнуть ярлыки и заставить их печатать, не теряя при этом. Я создал два набора тиков, показывая второй набор ниже другого, чтобы он выглядел так, как будто он шатается.

xaxis_stagger = function(positions,labels) {
  odd=labels[seq(1,length(labels),2)]
  odd_pos=positions[seq(1,length(positions),2)]
  even=labels[seq(2,length(labels),2)]  
  even_pos=positions[seq(2,length(positions),2)]
  axis(side=1,at=odd_pos,labels=odd)
  axis(side=1,at=even_pos,labels=even,padj=1.5)
}

Таким образом, вы даете позиции, в которых вы хотите, чтобы тики были, и метки для этих тиков, и это затем перегруппировало бы его на два набора оси и построило их на исходном графике. Исходный сюжет будет выполнен с помощью xaxt = "n".

Ответ 6

Возможно, нарисуйте и пометьте один тик за раз, вызывая axis несколько раз, используя mapply...

Например, рассмотрим следующие данные:

x = runif(100)*20
y = 10^(runif(100)*3)

Формула для y может выглядеть немного странной; он дает случайные числа, распределенные по трем порядкам, так что данные будут равномерно распределены на графике, где ось у находится в логарифмическом масштабе. Это поможет продемонстрировать полезность axTicks(), рассчитав для нас подходящие места для отметок на зарегистрированной оси.

По умолчанию:

plot(x, y, log = "y")

возвращений:

Обратите внимание, что 100 и 1000 ярлыков отсутствуют.

Вместо этого мы можем использовать:

plot(x, y, log = "y", yaxt = "n")
mapply(axis, side = 2, at = axTicks(2), labels = axTicks(2))

который вызывает axis() один раз для каждого местоположения тиков, возвращаемых axTicks(), таким образом выстраивая один тик за раз. Результат:

Что мне нравится в этом решении, так это то, что для рисования оси используется только одна строка кода, она печатает точно ту ось, которая была бы по умолчанию для R, за исключением того, что все метки помечены, а метки никуда не исчезают при изменении размера графика. :

Я не могу сказать, что ось полезна в примере с измененным размером, но это делает точку зрения о том, что метки оси являются постоянными!

Для первого (по умолчанию) графика, обратите внимание, что R будет пересчитывать местоположения тиков при изменении размера.

Для второго (всегда помеченного) графика количество и расположение меток не пересчитываются при изменении размера изображения. Тики оси, рассчитанные с помощью axTicks, зависят от размера окна отображения, когда график впервые рисуется.

Если вы хотите использовать определенные места для галочек, попробуйте что-то вроде:

plot(x, y, log = "y", yaxt = "n")
mapply(axis, side = 2, at = c(1,10,100, 1000), labels = c("one", "ten", "hundred", "thousand"))

который дает:

enter image description here