¿Cómo implementar una escala de color 2-d (tono x luminancia)?

Aquí hay un juguetedata.frame eso ilustra el problema (la versión más básica del mismo, es decir, habrá una arruga adicional más adelante):

df <- read.table(textConnection(
"toxin  dose    x   y
A   1   0.851   0.312
A   10  0.268   0.443
A   100 0.272   0.648
B   1   0.981   0.015
B   10  0.304   0.658
B   100 0.704   0.821
C   1   0.330   0.265
C   10  0.803   0.167
C   100 0.433   0.003
D   1   0.154   0.611
D   10  0.769   0.616
D   100 0.643   0.541
"), header = TRUE)

Quiero hacer un diagrama de dispersión de estos datos en los que la toxina está indicada por el tono de los puntos, y la dosis está indicada por su luminosidad (para una primera aproximación, una dosis baja debería corresponder a una alta luminosidad).

El aspecto particularmente desafiante de este problema de visualización es que la leyenda tendría que ser un color bidimensionalcuadrícula (en lugar de un color unidimensionalbar), con las filas correspondientes a latoxin variable y las columnas correspondientes adose (o una transformación del mismo).

La arruga adicional a la que aludí anteriormente es que los datos realmente incluyen una observación de control, donde la dosis es diferente de todas las demás (observe la fila con toxina = "Z", a continuación):

df <- read.table(textConnection(
"toxin  dose    x   y
A   1   0.851   0.312
A   10  0.268   0.443
A   100 0.272   0.648
B   1   0.981   0.015
B   10  0.304   0.658
B   100 0.704   0.821
C   1   0.330   0.265
C   10  0.803   0.167
C   100 0.433   0.003
D   1   0.154   0.611
D   10  0.769   0.616
D   100 0.643   0.541
Z   0.001   0.309   0.183
"), header = TRUE)

El punto para la toxina de control ("Z") debe ser un solo punto gris. (Está bien si la leyenda de la cuadrícula de color 2D no incluye el valor de control, pero en este caso debería haber al menos una leyenda que identifique su punto de manera apropiada).

En resumen, el problema tiene tres partes:

Representar la toxina y la dosis por matiz y luminancia, respectivamente.Haz una leyenda de cuadrícula de color 2D.Las leyendas deben identificar el punto de control.

A continuación se muestra lo que he logrado hasta ahora.

La única forma en que puedo pensar para resolver el primer aspecto del problema sería dedicar una capa diferente a cada toxina y usar un gradiente de color basado en la dosis.

Desafortunadamente, no parece haber una manera de especificar una escala de gradiente diferente para cada capa.

Más específicamente, primero defino lo siguiente:

library(ggplot2)

hues <- RColorBrewer::brewer.pal(4, "Set1")

gradient <- function (hue_index) {
  scale_color_gradient(high = hues[hue_index],
                       low = "white",
                       trans = "log",
                       limits = c(0.1, 100),
                       breaks = c(1, 10, 100))
}

baseplot <- ggplot(mapping = aes(x = x, y = y, color = dose))

La primera capa, por sí misma, parece prometedora:

(
 baseplot
          + geom_point(data = subset(df, toxin == "A"), size = 4)
          + gradient(1)
)

Pero cuando agrego la segunda capa ...

(
 baseplot
          + geom_point(data = subset(df, toxin == "A"), size = 4)
          + gradient(1)
          + geom_point(data = subset(df, toxin == "B"), size = 4)
          + gradient(2)
)

... recibo la siguiente advertencia:

Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.

Y, efectivamente, esta es la trama que obtengo:

No he podido encontrar una manera de definir diferentes capas, cada una con su propia escala de colores.

Respuestas a la pregunta(2)

Su respuesta a la pregunta