2016-08-15 17 views
11

Tôi muốn tạo một hình dạng đường hoặc hình chữ nhật tương tác, sao cho mỗi phân đoạn hoặc hình chữ nhật cung cấp thông tin khác nhau khi người dùng di chuột qua nó. Tôi đã xem trong số htmlwidgets showcase và tôi nghĩ rằng lôgic trông đầy hứa hẹn. (Tôi mở cho các phương pháp liên quan đến R khác.)Đoạn thẳng hoặc hình chữ nhật có thông tin di chuột trong hình vẽ R

Dưới đây là một ví dụ đơn giản. Tôi có thể tạo ra một âm mưu của các điểm kết thúc (t1 và t2) cung cấp thông tin di chuột. Nhưng tôi muốn thông tin di chuột xuất hiện bất cứ lúc nào người dùng di chuyển qua khoảng trống giữa hai điểm kết thúc).

Tôi có thể thêm đoạn đường bằng cách sử dụng add_trace(), nhưng tôi không thể di chuột để hoạt động. Và nếu tôi thêm các đoạn thẳng thứ hai, tôi nhận được một thông báo lỗi:

Error in plot_ly(data = mydat, x = t2, y = y, mode = "markers", hoverinfo = "text", : 
    requires numeric/complex matrix/vector arguments 

tôi có thể thêm hình chữ nhật bằng layout(), nhưng một lần nữa, tôi không thể có được sự di chuột để làm việc. Trong trường hợp ai đó gợi ý cách để lấy các đối số di chuột để làm việc cho một trong hai cách tiếp cận, tôi cũng sẽ hoan nghênh các đề xuất về cách mã này cho một số lượng lớn phân đoạn/hình chữ nhật (không chỉ 2 như trong ví dụ đơn giản này).).

Mọi đề xuất?

mydat <- data.frame(t1=c(1, 3), t2=c(4, 5), y=c(1, 2), task=c("this", "that")) 
library(plotly) 

# attempt with one line segment - hover doesn't work 
plot_ly(data=mydat, x=t2, y=y, mode="markers", 
    hoverinfo="text", text=task) %>% 
add_trace(data=mydat, x=t1, y=y, mode="markers", 
    hoverinfo="text", text=task) %>% 
add_trace(
    x=c(mydat$t1[1], mydat$t2[1]), y=c(mydat$y[1], mydat$y[1]), 
    mode="lines", hoverinfo="text", text=mydat$task[1]) 

# attempt with both line segments - 
# Error in plot_ly, requires numeric/complex matrix/vector arguments 
plot_ly(data=mydat, x=t2, y=y, mode="markers", 
    hoverinfo="text", text=task) %>% 
add_trace(data=mydat, x=t1, y=y, mode="markers", 
    hoverinfo="text", text=task) %>% 
add_trace(
    x=c(mydat$t1[1], mydat$t2[1]), y=c(mydat$y[1], mydat$y[1]), 
    mode="lines", hoverinfo="text", text=mydat$task[1]) %*% 
add_trace(
    x=c(mydat$t1[2], mydat$t2[2]), y=c(mydat$y[2], mydat$y[2]), 
    mode="lines", hoverinfo="text", text=mydat$task[2]) 

# attempt with rectangles - hover doesn't work 
plot_ly(data=mydat, x=t2, y=y, mode="markers", 
    hoverinfo="text", text=task) %>% 
add_trace(data=mydat, x=t1, y=y, mode="markers", 
    hoverinfo="text", text=task) %>% 
layout(shapes=list(
    list(type="rect", x0=mydat$t1[1], x1=mydat$t2[1], xref="x", 
    y0=mydat$y[1], y1=mydat$y[1]+0.1, yref="y", 
    hoverinfo="text", text=mydat$task[1]), 
    list(type="rect", x0=mydat$t1[2], x1=mydat$t2[2], xref="x", 
    y0=mydat$y[2], y1=mydat$y[2]+0.1, yref="y", 
    hoverinfo="text", text=mydat$task[2]) 
)) 

Trả lời

3

Bạn có thể sử dụng highcharter, mà kết thúc tốt đẹp các thư viện Highcharts.js.

# note i'm renaming y to x, since that's how highcharts will treat this dataset 
mydat <- data.frame(t1=c(1, 3), t2=c(4, 5), x=c(1, 2), task=c("this", "that")) 

library(highcharter) 

highchart(hc_opts = list(
    chart = list(inverted = 'true') 
)) %>% 
    hc_add_series_df(data = mydat, type = 'columnrange', 
        group = task, 
        x = x, low = t1, high = t2) 

enter image description here

trình chỉ tốt với không có mã bổ sung cần thiết cho một số lượng lớn các thanh:

set.seed(123) 
n <- 20 
largedat <- data.frame(t1 = runif(n, 1, 10), 
         x = 1:n, 
         task = paste('series', 1:n)) 
largedat$t2 <- largedat$t1 + runif(n, 2, 5) 

highchart(hc_opts = list(
    chart = list(inverted = 'true') 
)) %>% 
    hc_add_series_df(data = largedat, type = 'columnrange', 
        group = task, 
        x = x, low = t1, high = t2) %>% 
    hc_legend(enabled = FALSE) # disable legend on this one 

enter image description here

3

Bạn có thể nhận thông tin di chuột dọc theo một đường bằng cách đặt nhiều điểm trên đường. Bạn không cần phải đặt dấu tại những điểm này, do đó cốt truyện vẫn sẽ trông giống nhau:

NP=100 
mydat <- data.frame(t1=seq(1,3,len=NP), t2=seq(4,5,len=NP), y1=rep(1,NP), y2=rep(2,NP)) 

plot_ly(data=mydat) %>% 
    add_trace(x=t1, y=y1, mode="lines", hoverinfo="text", text="hello") %>% 
    add_trace(x=t2, y=y2, mode="lines", hoverinfo="text", text="there") 

enter image description here

Mở rộng này để hình chữ nhật, chúng ta có thể làm

plot_ly() %>% 
    add_trace(x=c(seq(1,3,len=NP), rep(3,NP), seq(3,1,len=NP), rep(1,NP)), 
      y=c(rep(1,NP), seq(1,2,len=NP), rep(2,NP), seq(2,1,len=NP)), 
      mode="lines", hoverinfo="text", text="A sublime rectangle") %>% 
    layout(hovermode = 'closest') 

Hoặc, nếu bạn muốn gắn nhãn mỗi bên của hình chữ nhật riêng biệt

plot_ly() %>% 
    add_trace(x=c(seq(1,3,len=NP), rep(3,NP), seq(3,1,len=NP), rep(1,NP)), 
      y=c(rep(1,NP), seq(1,2,len=NP), rep(2,NP), seq(2,1,len=NP)), 
      mode="lines", hoverinfo="text", 
      text=c(rep("bottom",NP),rep("right",NP),rep("top",NP),rep("left",NP))) %>% 
    layout(hovermode = 'closest') 

Và đối với dia các đường gonal:

plot_ly() %>% 
    add_trace(x=seq(1,3,len=NP), y=seq(1,2,len=NP), mode="lines", hoverinfo="text", text="diagonal") %>% 
    layout(hovermode = 'closest') 

Để trả lời cho câu hỏi phụ "cách mã này cho một số lượng lớn phân đoạn/hình chữ nhật"? Bạn không chỉ định số lượng "số lớn". Nhưng những gì tôi có thể nói là thêm nhiều dấu vết riêng biệt trong cốt truyện có thể làm cho nó khá chậm để xử lý. Không chậm chạp với một số lượng lớn dấu vết. Cách xung quanh việc này là thêm tất cả các đoạn đường của bạn vào một dấu vết. Đối với một số hiệu ứng (như điều khiển màu riêng biệt với nhóm và mục chú giải), có thể cần thêm giá trị NA tách các đoạn và sử dụng tùy chọn connectgaps=FALSE trong add_trace (xem herehere), nhưng điều đó không cần thiết cho trường hợp đơn giản này . Dưới đây là một ví dụ rất nhỏ

line1 <- data.frame(x=seq(3.5,4.5,len=NP), y=rep(2.5,NP), text="hello") 
line2 <- data.frame(x=seq(3,3.5,len=NP), y=seq(3,2.5,len=NP), text="mouth") 
line3 <- data.frame(x=seq(4.5,5,len=NP), y=seq(2.5,3,len=NP), text="mouth") 
line4 <- data.frame(x=rep(4,NP), y=seq(2.75,3.5,len=NP), text="nose") 
rect1 <- data.frame(x=c(seq(2,6,len=NP), rep(6,NP), seq(6,2,len=NP), rep(2,NP)), 
        y=c(rep(2,NP), seq(2,4.5,len=NP), rep(4.5,NP), seq(4.5,2,len=NP)), 
        text="head") 
rect2 <- data.frame(x=c(seq(2.5,3.5,len=NP), rep(3.5,NP), seq(3.5,2.5,len=NP), rep(2.5,NP)), 
        y=c(rep(3.5,NP), seq(3.5,4,len=NP), rep(4,NP), seq(4,3.5,len=NP)), 
        text="left eye") 
rect3 <- data.frame(x=c(seq(4.5,5.5,len=NP), rep(5.5,NP), seq(5.5,4.5,len=NP), rep(4.5,NP)), 
        y=c(rep(3.5,NP), seq(3.5,4,len=NP), rep(4,NP), seq(4,3.5,len=NP)), 
        text="right eye") 

trace_dat <- rbind(line1, line2, line3, line4, rect1, rect2, rect3) 

plot_ly(data=trace_dat, x=x, y=y, mode="lines", hoverinfo="text", text=text, group = text) %>% 
    layout(hovermode = 'closest') 

enter image description here

Các vấn đề liên quan