2017-12-26 8 views
6

folgendes Beispiel:Display aufgetragen nur Daten in der Legende

library(ggplot2) 
df = data.frame(x = 1:5, y = 1:5, z = c('a', 'a', 'a', 'b', 'b')) 

ggplot(df, aes(x, y, col = z)) + geom_line() + geom_point() + 
    coord_cartesian(xlim = c(1, 2.5)) 

enter image description here

nur Daten aus dem a Eimer angezeigt wird, doch beide a und b in der Legende angezeigt. Wie kann ich das beheben, sodass nur der Bucket, der tatsächlich geplottet wird, in der Legende angezeigt wird?

Für Kontext - ich begegne dies beim Versuch in shiny.

+0

Wenn Sie außerhalb des sichtbaren Zeichenbereichs Punkte haben, was nach dem Zoomen der Fall ist, ist das Standardverhalten das Anzeigen aller unterschiedlichen Punktklassen. – Heikki

+3

@Heikki haha, ok, es ist nicht von mir gewünscht - so die Frage – eddi

+1

können Sie verwenden, was von 'shiny' zurückgegeben wird, um die Daten zu filtern, anstatt mit' coord_cartesian' – bouncyball

Antwort

5

Kann die Filterung auf z Ihren tatsächlichen Anwendungsfall abdecken? Zum Beispiel:

library(tidyverse) 

df = data.frame(x = 1:5, y = 1:5, z = c('a', 'a', 'a', 'b', 'b')) 

ggplot(df %>% filter(z %in% z[between(x,1,2.5)]), 
     aes(x, y, col = z)) + 
    geom_line() + geom_point() + 
    coord_cartesian(xlim = c(1, 2.5)) 

Oder in einer Funktion, die für benutzerdefinierte ästhetische Variablen weiter verallgemeinert werden könnte. (Ich habe aktualisiert auch die Funktion Interpolation verwenden Linien sogar in Plot Regionen zu zeichnen, die keine Datenpunkte enthalten, so lange wie mindestens eine Verbindungslinie zwischen den Punkten verlaufen durch die Plotregion.)

my_plot = function(xrng, data=df, step=0.01) { 

    levs = unique(data[["z"]]) 
    n = length(levs) 

    # Generate interpolated data frame so we can plot lines even if 
    # no points appear in the graph region 
    dat_interp = split(data, data$z) %>% 
    map_df(function(d) { 
     x = seq(min(d$x), max(d$x), step) 
     data.frame(z=rep(unique(d$z), each=length(x)), 
       x, y=rep(approx(d$x, d$y, xout=x)$y, n)) 
    }) 

    ggplot(dat_interp %>% filter(z %in% z[between(x,xrng[1],xrng[2])]), 
     aes(x, y, col = z)) + 
    geom_point(data=data %>% filter(z %in% z[between(x,xrng[1],xrng[2])])) + 
    geom_line() + 
    coord_cartesian(xlim = xrng) + 
    scale_color_manual(values=setNames(hcl(seq(15,375,length=n+1)[1:n],100,65), levs)) 
} 


gridExtra::grid.arrange(
    my_plot(c(1,2.5)), 
    my_plot(c(1,4)), 
    my_plot(c(3,4)), 
    my_plot(c(4.3,6)), 
    my_plot(c(1.1,1.6)), 
    my_plot(c(4.2,4.9))) 

enter image description here

+0

Danke! Nach einigem Klicken - das deckt nicht den Fall 'my_plot (c (1.1, 1.6)) 'ab, aber es ist eine gute Lösung für mich. – eddi

+1

Ich habe die Antwort aktualisiert, um Interpolation zu verwenden, um den Fall zu behandeln, dass keine Datenpunkte in der Diagrammregion vorhanden sind. – eipi10