2016-10-16 29 views
5

Yeni bir Geom türü oluşturmak istiyorum: Candlestick Charts gibi bir şey olan geom_ohlc(), açık yüksek-düşük-stok çizimi yakın veri.

bu Hadley's article öğrenme sonra: ben sadece çubuğunun rengini düşünmüyoruz, basitlik için

GeomOHLC <- ggproto(`_class` = "GeomOHLC", `_inherit` = Geom, 

       required_aes = c("x", "op", "hi", "lo", "cl"), 

       draw_panel = function(data, panel_scales, coord){ 

        coords <- coord$transform(data, panel_scales) 
        browser() # <<-- here is where I found the problem 
        grid::gList(
        grid::rectGrob(
         x = coords$x, 
         y = pmin(coords$op, coords$cl), 
         vjust = 0, 
         width = 0.01, 
         height = abs(coords$op - coords$cl), 
         gp = grid::gpar(col = coords$color, fill = "yellow") 
        ), 
        grid::segmentsGrob(
         x0 = coords$x, 
         y0 = coords$lo, 
         x1 = coords$x, 
         y1 = coords$hi 
         ) 
        ) 
       }) 
    geom_ohlc <- function(data = NULL, mapping = NULL, stat = "identity", position = "identity", na.rm = FALSE, show.legend = NA, inherit.aes = TRUE, ...) 
    { 
     layer(
     geom = GeomOHLC, mapping = mapping, data = data, 
     stat = stat, position = position, show.legend = show.legend, 
     inherit.aes = inherit.aes, params = list(na.rm = na.rm, ...) 
    ) 
    } 
    dt <- data.table(x = 1:10, open = 1:10, high = 3:12, low = 0:9, close = 2:11) 
    p <- ggplot(dt, aes(x = x, op = open, hi = high, lo = low, cl = close)) + 
     geom_ohlc() 
    p 

: Bu çalıştı.

screenshot

Ben browser() ggproto içindeki işlevini ekleyin ve ben coord$transform [interverl içine op, hi, lo, cl estetik dönüşümü olmadığı bulundu:

sonuç arsa böyledir 0,1]. Bu sorun nasıl çözülür ?

Ayrıca, Hadley'in makalesi dışında kendi Geom türünüzü oluşturma hakkında başka belgeler var mı?

+0

Suçlama, "coord $ transform" işlevinde çağrılan "transform_position()" gibi görünüyor. Kod, yalnızca sütunları 'x' ve' y' adlı data.frame dosyasında dönüştüreceğini gösterir. Sorununuza bir çözüm bilmiyorum ama yeniden boyutlandırmanız için * gerekip gerekmediğini düşünmeye çalışacağım (?). – ddiez

+0

İkinci düşüncede de aynı kod, ölçeklerin birkaçının "x" ve/veya "y" olma olasılığını da ortaya koymaktadır. Belki orada bir şey var mı? – ddiez

+0

Ayrıca, 'ggplot2 ::: aes_to_scale' fonksiyonu,' data.frame' isimlerinin x' veya 'y' skalasına göre eşleştirilmesidir. Belgelere bakacak olursanız, “x”, “xmin”, “xmax”, “xend”, “xintercept” veya y ekseni için eşdeğer estetiği kullanmalısınız. Ayrıca “? Transform_position” da belirtilmiştir. Bence değişkenlerinizin haritasını çözmek için bir yol bulabilirseniz, probleminizi çözeceksiniz. – ddiez

cevap

2

OP'nin sorusu altında yer alan yorumlarda belirtildiği gibi, transform_position() içindeişlevinin içinde, coord$transform tarafından çağrılmaktadır. Dönüşümler, x, xmin, xmax, xend, xintercept adlı değişkenlerle ve y eksenine eşdeğerler ile sınırlıdır. Bu transform_position için yardım belirtilen:

Description

Convenience function to transform all position variables.

Usage

transform_position(df, trans_x = NULL, trans_y = NULL, ...) Arguments

trans_x, trans_y Transformation functions for x and y aesthetics. (will transform x, xmin, xmax, xend etc) ... Additional arguments passed to trans_x and trans_y.

bir geçici çözüm yerine OP tarafından kullanılan değişken isimleri bu değişken adlarını kullanmak olacaktır. Aşağıdaki kod değişkenleri dönüştürmek için çalışır, ancak başka bir yerde başarısız olur (en sonunda bakın). İstenen arsa ayrıntılarını bilmiyorum, bu yüzden bu hatayı gidermeye çalışmadım.

GeomOHLC <- ggproto(
    `_class` = "GeomOHLC", 
    `_inherit` = Geom, 

    required_aes = c("x", "yintercept", "ymin", "ymax", "yend"), 

    draw_panel = function(data, panel_scales, coord) { 
    coords <- coord$transform(data, panel_scales) 
    #browser() # <<-- here is where I found the problem 
    grid::gList(
     grid::rectGrob(
     x = coords$x, 
     y = pmin(coords$yintercept, coords$yend), 
     vjust = 0, 
     width = 0.01, 
     height = abs(coords$op - coords$cl), 
     gp = grid::gpar(col = coords$color, fill = "yellow") 
    ), 
     grid::segmentsGrob(
     x0 = coords$x, 
     y0 = coords$ymin, 
     x1 = coords$x, 
     y1 = coords$ymax 
    ) 
    ) 
    } 
) 
geom_ohlc <- 
    function(data = NULL, 
      mapping = NULL, 
      stat = "identity", 
      position = "identity", 
      na.rm = FALSE, 
      show.legend = NA, 
      inherit.aes = TRUE, 
      ...) 
    { 
    layer(
     geom = GeomOHLC, 
     mapping = mapping, 
     data = data, 
     stat = stat, 
     position = position, 
     show.legend = show.legend, 
     inherit.aes = inherit.aes, 
     params = list(na.rm = na.rm, ...) 
    ) 
    } 
dt <- 
    data.table(
    x = 1:10, 
    open = 1:10, 
    high = 3:12, 
    low = 0:9, 
    close = 2:11 
) 
p <- 
    ggplot(dt, aes(
    x = x, 
    yintercept = open, 
    ymin = high, 
    ymax = low, 
    yend = close 
)) + 
    geom_ohlc() 
p 

Bu değişkenler dönüşümleri ancak aşağıdaki hatayı üretir:

Error in unit(height, default.units) : 
    'x' and 'units' must have length > 0 

Ama umarım buradan işe yapılabilir.

NOT: Özgün değişken adları (op, hi, lo, cl) arasındaki eşlemeyi daha çok rasgele seçtim. Özel olarak yintercept iyi uymuyor gibi görünüyor. Belki de ggplot2'de rastgele ölçek değişken isimlerini desteklemeye ihtiyaç var mı?

+0

Bence noktayı aldın. 'Draw_panel' fonksiyonunun içindeki 'data' sütun isimlerini 'op, hi, lo, cl' 'den y, ymax, ymin, yend' 'e çevirmeye çalışıyorum. Daha sonra “copeds $ transfrom” bu sütunları [0, 1] 'e dönüştürmeyi bilir. –

İlgili konular