Separate legends for geom_ribbon aesthetics

My explanation was entirely off the mark! Although there can be data-type clashes that produce unintended ggplot behavior, that's not what's going on in your example. It appears there are two factors that are contributing to the behavior:

  1. the use of strings as placeholders that are later assigned values, and
  2. the splitting of attributes of a graphical element across legends

Here is a pair of examples that I think illustrate how legend behavior depends on both of these. (Full reprex at end of post.)

In the first example, all the aesthetics have the same source (the string 'a'), and lead to a single legend that combines them all:

library(tidyverse)                       

ggplot() +
  geom_tile(
    aes(
      0, 0, width = 1, height = 1,
      color = 'a',
      fill = 'a',
      linetype = 'a',
      alpha = 'a'
    ),
    linewidth = 1
  ) +
  scale_color_manual(name = 'cmb', values = 'red') +
  scale_fill_manual(name = 'cmb', values = 'blue') +
  scale_alpha_manual(name = 'cmb', values = 0.4) +
  scale_linetype_manual(name = 'cmb', values = 'dashed' )

However, if we give linetype and alpha a different source, 'b', we get this:

ggplot() +
  geom_tile(
    aes(
      0, 0, width = 1, height = 1,
      color = 'a',
      fill = 'a',
      linetype = 'b',
      alpha = 'b'
    ),
    linewidth = 1
  ) +
  scale_color_manual(name = 'cmb', values = 'red') +
  scale_fill_manual(name = 'cmb', values = 'blue') +
  scale_alpha_manual(name = 'cmb', values = 0.4) +
  scale_linetype_manual(name = 'cmb', values = 'dashed' )

Created on 2024-05-23 with reprex v2.0.2

The fact that there are now two legends corresponds to the fact that there are two sources for the data supplied to the aesthetics, but that is not all: The boundary of the rectangle is a line that incorporates the color and linetype aesthetics, but these are split between the two legends, and only one gets the graphical representation of the line, color (likely because of the order of the aesthetics of a line), and so the second legend has no "line" to be "dashed". (The light grey boundary in the second legend shows the "line" is missing.)

Full reprex
library(tidyverse)                       

ggplot() +
  geom_tile(
    aes(
      0, 0, width = 1, height = 1,
      color = 'a',
      fill = 'a',
      linetype = 'a',
      alpha = 'a'
    ),
    linewidth = 1
  ) +
  scale_color_manual(name = 'cmb', values = 'red') +
  scale_fill_manual(name = 'cmb', values = 'blue') +
  scale_alpha_manual(name = 'cmb', values = 0.4) +
  scale_linetype_manual(name = 'cmb', values = 'dashed' )

  

ggplot() +
  geom_tile(
    aes(
      0, 0, width = 1, height = 1,
      color = 'a',
      fill = 'a',
      linetype = 'b',
      alpha = 'b'
    ),
    linewidth = 1
  ) +
  scale_color_manual(name = 'cmb', values = 'red') +
  scale_fill_manual(name = 'cmb', values = 'blue') +
  scale_alpha_manual(name = 'cmb', values = 0.4) +
  scale_linetype_manual(name = 'cmb', values = 'dashed' )

Created on 2024-05-23 with reprex v2.0.2