Disclaimer: I have collected a few issues that could be improved in spineplots, some of which were already discussed in #657. I'm happy to start addressing the issues but would appreciate some guidance/feedback first. This can easily wait until after the summer vacation!
Border color
In #657 spineplots received border = par("fg") as the border color rather than border = icol. Wouldn't the latter be more consistent, e.g., with boxplot? Also, I think that this means that the border color cannot be set as an argument to tinyplot(...) or type_spineplot(...).
My suggestion would be to export a border = NULL argument in type_spineplot(). Possibly additionally switch to border = icol internally when the user specifies border = "by"?
As an illustration we can use the following code. The first plot shows the current border = par("fg") and the latter shows what we would get with border = icol.
tinyplot(species ~ bill_dep | sex, facet = "by", data = penguins, legend = FALSE, theme = "clean2")
by variable
The current implementation of the by variable was always just a poor interim solution which was only marginally better than saying that by was not supported.
The natural strategy would be to simply add further vertical splits for the by variable (in addition to the x variable). The basic idea is straightforward and can be approximated by using interaction(x, by).
ucb = as.data.frame(UCBAdmissions)
tinyplot(Admit ~ interaction(Gender, Dept, sep = "\n"), data = ucb, weights = Freq)
However, the spacing (tol) should be improved and it would also be possible to get nicer axis labels. This could be similar to what mosaicplot() in base R does:
mosaicplot(aperm(UCBAdmissions, 3:1), dir = c("v", "v", "h"), off = c(6, 3, 0), col = gray.colors(2, rev = TRUE), main = "")
An open question is whether this display should be produced with Gender as the by variable (i.e., Admit ~ Dept | Gender) or with Dept (i.e., Admit ~ Gender | Dept). For categorical x variables like here, I would find Gender as the by variable a bit more intuitive. However, it wouldn't look good to use the same display for a numeric x variable. So I think we should go with Dept as the by variable here.
Note that the display is similar to but not quite the same as the corresponding faceted display below. The crucial difference is that in the faceted display every Dept gets the same size for the facet. In contrast in the by display you should be able to see the marginal distribution of Dept as well, e.g., that there are more observations in department A than in department B.
tinyplot(Admit ~ Gender, data = ucb, facet = 1 ~ Dept, weights = Freq)
Black-based gray sequential colors
In the single-group case the sequential palette constructed from black is actually set up via gray.colors() to match what base R does in spineplot().
However, in the multi-group case the same is not done. See the left group below which really uses full black as the base color which is probably a bit too "heavy". Switching to gray.colors() here would also work better.
tinyplot(Admit ~ Gender | Dept, data = ucb, facet = 1 ~ Dept, weights = Freq)

Border color
In #657 spineplots received
border = par("fg")as the border color rather thanborder = icol. Wouldn't the latter be more consistent, e.g., with boxplot? Also, I think that this means that the border color cannot be set as an argument totinyplot(...)ortype_spineplot(...).My suggestion would be to export a
border = NULLargument intype_spineplot(). Possibly additionally switch toborder = icolinternally when the user specifiesborder = "by"?As an illustration we can use the following code. The first plot shows the current
border = par("fg")and the latter shows what we would get withborder = icol.byvariableThe current implementation of the
byvariable was always just a poor interim solution which was only marginally better than saying thatbywas not supported.The natural strategy would be to simply add further vertical splits for the
byvariable (in addition to thexvariable). The basic idea is straightforward and can be approximated by usinginteraction(x, by).However, the spacing (
tol) should be improved and it would also be possible to get nicer axis labels. This could be similar to whatmosaicplot()in base R does:An open question is whether this display should be produced with
Genderas thebyvariable (i.e.,Admit ~ Dept | Gender) or withDept(i.e.,Admit ~ Gender | Dept). For categoricalxvariables like here, I would findGenderas thebyvariable a bit more intuitive. However, it wouldn't look good to use the same display for a numericxvariable. So I think we should go withDeptas thebyvariable here.Note that the display is similar to but not quite the same as the corresponding faceted display below. The crucial difference is that in the faceted display every
Deptgets the same size for the facet. In contrast in thebydisplay you should be able to see the marginal distribution ofDeptas well, e.g., that there are more observations in department A than in department B.Black-based gray sequential colors
In the single-group case the sequential palette constructed from black is actually set up via
gray.colors()to match what base R does inspineplot().However, in the multi-group case the same is not done. See the left group below which really uses full black as the base color which is probably a bit too "heavy". Switching to
gray.colors()here would also work better.