2012-07-25 7 views
8

quiero lograr los siguientes resultados:Gráfico de burbuja para variables enteras donde la burbuja más grande tiene un diámetro de 1 (en la escala del eje xo y)

  1. reescalar el tamaño de las burbujas de tal manera que la más grande de la burbuja tiene un diámetro de 1 (en lo que tiene la escala más comprimido de la x y ejes Y).
  2. reescalar el tamaño de las burbujas de tal manera que la burbuja más pequeña tiene un diámetro de 1 mm
  3. tienen una leyenda con el primer y último puntos de la no-cero de frecuencia mínima y la frecuencia máxima.

Lo mejor que he podido hacer es lo siguiente, pero necesito una solución más general en la que se calcule el valor de maxSize en lugar de código fijo. Si lo estuviera haciendo en los trazados R tradicionales, usaría par ("pin") para calcular el tamaño del área de trazado y trabajar hacia atrás, pero no puedo entender cómo acceder a esta información con ggplot2. ¿Alguna sugerencia?

library(ggplot2) 
agData = data.frame(
    class=rep(1:7,3), 
    drv = rep(1:3,rep(7,3)), 
    freq = as.numeric(xtabs(~class+drv,data = mpg)) 
) 

agData = agData[agData$freq != 0,] 
rng = range(agData$freq) 
mn = rng[1] 
mx = rng[2] 
minimumArea = mx - mn 
maxSize = 20 
minSize = max(1,maxSize * sqrt(mn/mx)) 
qplot(class,drv,data = agData, size = freq) + theme_bw() + 
    scale_area(range = c(minSize,maxSize), 
      breaks = seq(mn,mx,minimumArea/4), limits = rng) 

Aquí es lo que parece hasta ahora: enter image description here

+0

¿Cómo se llega a "20" para el 'maxSize' en su ejemplo? – A5C1D2H2I1M1N2O1R2T1

Respuesta

7

Cuando hay ggplot, enrejado o de otro paquete de alto nivel parece hacer el trabajo sin horas de puesta a punto que siempre vuelven a los gráficos de base. El siguiente código le proporciona lo que desea y, a continuación, tengo otro ejemplo basado en cómo lo trazaría.

Sin embargo, tenga en cuenta que he configurado el radio máximo a 1 cm, pero solo divida size.range/2 para obtener el diámetro en su lugar. Solo pensé que el radio me dio tramas más agradables, y probablemente quieras ajustar las cosas de todos modos.

size.range <- c(.1, 1) # Min and max radius of circles, in cm 

# Calculate the relative radius of each circle 
radii <- sqrt(agData$freq) 
radii <- diff(size.range)*(radii - min(radii))/diff(range(radii)) + size.range[1] 

# Plot in two panels 
mar0 <- par("mar") 
layout(t(1:2), widths=c(4,1)) 

# Panel 1: The circles 
par(mar=c(mar0[1:3],.5)) 
symbols(agData$class, agData$drv, radii, inches=size.range[2]/cm(1), bg="black") 

# Panel 2: The legend 
par(mar=c(mar0[1],.5,mar0[3:4])) 
symbols(c(0,0), 1:2, size.range, xlim=c(-4, 4), ylim=c(-2,4), 
     inches=1/cm(1), bg="black", axes=FALSE, xlab="", ylab="") 
text(0, 3, "Freq") 
text(c(2,0), 1:2, range(agData$freq), col=c("black", "white")) 

# Reset par settings 
par(mar=mar0) 

Plot suggestion 1

Ahora sigue mi sugerencia. El círculo más grande tiene un radio de 1 cm y el área de los círculos es proporcional a agData$freq, sin forzar un tamaño del círculo más pequeño. Personalmente creo que esto es más fácil de leer (tanto el código como la figura) y se ve mejor.

with(agData, symbols(class, drv, sqrt(freq), 
    inches=size.range[2]/cm(1), bg="black")) 
with(agData, text(class, drv, freq, col="white")) 

Plot suggestion 2

Cuestiones relacionadas