Увеличьте полигональное разрешение полярных участков ggplot

Я рисую большую полярную диаграмму/круговую диаграмму из 40 + баров/колец с ggplot2 (используя geom_bar и coord_polar (theta = "y" )), и я обнаружил, что сжатие участка оси y приводит к тому, что самые внутренние кольца имеют очень низкое разрешение многоугольника.

Кто-нибудь знает способ поднять полигональное разрешение?

df <- data.frame(
  x = sort(sample(1:40, 400, replace=TRUE)), 
  y = sample(0:9, 400, replace=TRUE)
)


ggplot(df, aes(x=x, y=y, fill=y)) + 
  geom_bar(stat='identity', position="fill") + 
  coord_polar(theta="y") + 
  scale_fill_continuous(low="blue", high="pink")

enter image description here

Это то, что я имею в виду под геометрическим разрешением, которое я пытаюсь достичь. Мне это удалось, построив только 5 уровней.

enter image description here

Когда я увеличиваю до 40 уровней, центральные полигоны теряют свою гладкость и становятся слишком зубчатыми, например:

enter image description here

Ответы

Ответ 1

Проблема связана с функцией ggplot2:::coord_munch, которая имеет аргумент segment_length со значением по умолчанию 0,01:

https://github.com/hadley/ggplot2/blob/master/R/coord-munch.r

Я не думаю, что в аргументах нет места для передачи аргументов coord_munch segment_length. Один из способов решения этой проблемы - заменить coord_munch на функцию-оболочку, которая имеет другое значение по умолчанию для segment_length.

# Save the original version of coord_munch
coord_munch_old <- ggplot2:::coord_munch

# Make a wrapper function that has a different default for segment_length
coord_munch_new <- function(coord, data, range, segment_length = 1/500) {
  coord_munch_old(coord, data, range, segment_length)
}
# Make the new function run in the same environment
environment(coord_munch_new) <- environment(ggplot2:::coord_munch)

# Replace ggplot2:::coord_munch with coord_munch_new
assignInNamespace("coord_munch", coord_munch_new, ns="ggplot2")

После этого вы можете снова запустить пример:

set.seed(123)
df <- data.frame(
  x = sort(sample(1:40, 400, replace=TRUE)), 
  y = sample(0:9, 400, replace=TRUE)
)

pdf('polar.pdf')
ggplot(df, aes(x=x, y=y, fill=y)) + 
  geom_bar(stat='identity', position="fill") + 
  coord_polar(theta="y") + 
  scale_fill_continuous(low="blue", high="pink")
dev.off()

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

Ответ 2

В дополнение к правильной диагностике и обходному пути wch выше, Жан-Оливье предлагает альтернативное обходное решение через ggplot2 Google Group:

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

ggplot(df, aes(x=x+100, y=y, fill=y)) +
 geom_bar(stat='identity', position="fill") +
 coord_polar(theta="y") +
 scale_fill_continuous(low="blue", high="pink")

Спасибо всем.