Я хочу построить разреженные данные с использованием разреженных масштабов с красивыми шестнадцатеричными метками, используя ggplot2 в GNU R. У меня есть фрейм данных и функция метки, подобные приведенным ниже:
require(ggplot2)
df <- data.frame(src = round(c(0x10000:0x10100,runif(100, 0x1000,0x100000))),
dst = round(c(0x11000:0x11100,runif(100,0x1000,0x100000))))
hexlabels=function(x) {base::sprintf("0x%x",as.integer(x))}
Ключ в том, что данные очень редко разбросаны по широкому диапазону. Кроме того, есть смесь плотных участков с разреженными участками.
График базовой точки ggplot(df, aes(x = src, y = dst)) + geom_point() + scale_x_continuous(labels = hexlabels) + scale_y_continuous(labels = hexlabels)
не представляет плотную часть графика адекватным образом, и шестнадцатеричные метки расположены на неудачных разрывах.
Поэтому для решения первой проблемы я попытался использовать дискретные шкалы с преобразованием в коэффициенты:
ggplot(df, aes(x = factor(src), y = factor(dst))) +
geom_point() +
scale_x_discrete(labels = hexlabels) +
scale_y_discrete(labels = hexlabels)
Этот результат представляет собой график, который показывает адекватное представление точек, но совершенно нечитаемые дискретные шкалы.
До сих пор я использовал индексы, чтобы вернуться к непрерывным масштабам, чтобы получить читаемый результат, но без значимых меток.
ggplot(df, aes(x = as.numeric(factor(src)),
y = as.numeric(factor(dst)))) + geom_point()
Можете ли вы дать мне подсказки, как реализовать этот график с аналогичными масштабами, но с использованием исходных значений src
и dst
в качестве меток на осях, возможно, с хорошими перерывами для шестнадцатеричных значений?
До сих пор я безуспешно пытался преобразовать мои данные src
и dst
в отдельные предварительно обработанные фреймы данных (ссылочные лайки):
require(scales)
as.referencelike <- function(x) {
data.frame(ref = x, idx = as.numeric(as.factor(x))) }
df$rlsrc = as.referencelike(df$src)
df$rldst = as.referencelike(df$dst)
referencelike_trans <- trans_new("referencelike",
transform = function(x) {x$idx},
inverse = identity)
ggplot(df, aes(x = rlsrc, y = rldst)) + geom_point() +
scale_x_continuous(trans = referencelike_trans) +
scale_y_continuous(trans = referencelike_trans)
Это приводит к ошибке Error: Aesthetics must be either length 1 or the same as the data (357): x, y
, вероятно потому, что ggplot принимает длину небольших фреймов данных и не проверяет преобразование. Также необходимо реализовать обратное преобразование. Указанное преобразование на самом деле не вызывает.
Второй моей попыткой было создать собственный класс:
require(scales)
reference <- setClass("reference", slots = c("ref","idx"))
as.reference <- function(y) {
i = as.numeric(as.factor(y))
Map(function(a,b) {
reference(ref = a, idx = b) }, y, i)}
df$rsrc = as.reference(df$src)
df$rdst = as.reference(df$dst)
reference_trans <- trans_new("reference",
transform = function(x) {x@idx},
inverse = identity)
as.data.frame.reference <- function(x,...) { data.frame(ref = x@ref, idx = x@idx, ...) }
ggplot(df, aes(x = rsrc, y = rdst)) + geom_point() +
scale_x_continuous(trans = reference_trans) +
scale_y_continuous(trans = reference_trans)
В этот момент я получаю следующую ошибку: Error: geom_point requires the following missing aesthetics: x, y
До сих пор я не пробовал реализовать вариант pretty_breaks
для шестнадцатеричных данных.
Любая помощь приветствуется!