Excelsior
Excelsior

Reputation: 181

problems with the distance between the side plot and main plot using ggside

I am using ggside to plot a contour plot as a main plot and a spectrum on the left y-axis and the top x-axis.

rm(list = ls(all = TRUE))

if (!require("ggplot2")) install.packages("ggplot2")
if (!require("ggside")) install.packages("ggside")

# set theme

theme_set(
  theme(axis.line = element_blank(),
        axis.ticks = element_line(color = "black", size = 0.5, linetype = 1),
        plot.title = element_text(color = "black", size = 18,
                                  hjust = 0, vjust = 2),
        axis.title = element_text(color = "black", size = 16),
        axis.text = element_text(color = "black", size = 14),
        plot.tag = element_text(color = "black", size = 28),
        axis.ticks.length = unit(5, "pt"),
        plot.margin = margin(0.25, 0.25, 0.25, 0.25, "cm"),
        panel.border = element_rect(color = "black", size = 1, linetype = 1, fill = NA),
        panel.background = element_blank(),
        panel.grid = element_blank(),
        legend.title = element_blank(),
        legend.text = element_text(color = "black", size = 14),
        legend.text.align = 0.5,
        legend.background = element_rect(color = "transparent", fill = "white"),
        legend.key = element_rect(color = "transparent", fill = "white"),
        legend.margin = margin(5, 5, 5, 5, "pt")))

# contour

set.seed(230727)

z.1 <- runif(n = 100, min = -5, max = 20)
x.1 <- y.1 <- seq(1, length(z.1)/10, 1)
tmp <- expand.grid(x.1, y.1)
x.1 <- tmp[,1]
y.1 <- tmp[,2]

df.1 <- data.frame(x = x.1, y = y.1)
df.1$z <- z.1
df.1$level <- as.numeric(df.1$z)

# line plot

y.2 <- cbind(runif(n = length(z.1)/10, min = -5, max = 20),
             runif(n = length(z.1)/10, min = -5, max = 20))
x.2 <- seq(1, NROW(y.2), 1)

df.2 <- data.frame(x = x.2, y = y.2)

# plot data

ggplot(df.1, aes(x = x, y = y)) +
  geom_contour(aes(z = z, color = after_stat(level))) + 
  labs(x = expression(tilde(nu)[1] / cm^{-1}), y = expression(tilde(nu)[2] / cm^{-1}),
       tag = "A") +
  scale_x_continuous(expand = c(0,0)) +
  scale_y_continuous(expand = c(0,0),
                     position = "right") +
  theme(
    plot.tag.position = c(0.05, 0.95),
    legend.position = "bottom",
    legend.direction = "horizontal",
    legend.key.size = unit(0.5, "cm"),
    legend.key.width = unit(2,"cm"),
    aspect.ratio = 1) +
  ggside(x.pos = "top", y.pos = "left") +
  geom_xsideline(data = df.2, aes(x = x, y = y.1)) +
  geom_ysideline(data = df.2, aes(x = y.2, y = x), orientation = "y") +
  theme(ggside.panel.scale = 0.125,
        ggside.axis.text = element_blank(),
        ggside.axis.ticks = element_blank())

plot 1 without expand scale

The plot looks as expected.

When adding and expanded scale to the side plots using scale_xsidey_continuous(expand = c(0.1, 0.1)) and scale_ysidey_continuous(expand = c(0.1, 0.1)), the distance between the left side plot and the main plot increases.

plot 2 with expand scale

When the side plot on the y-axis is on the right side, these commands don't affect the plot this way

plot 3 with expand scale

Does anybody know how to solve this problem?

Upvotes: 0

Views: 90

Answers (1)

stefan
stefan

Reputation: 125697

First, while expanding the y scale for the x-side plot increases the spacing between the y side plot and the main plot this is IMHO an (unintended) side effect and most likely a bug.

This can be seen by checking out different values for the expansion, e.g. the default, your value of .1 and a super large value of 10:

  • Adding some expansion on the side plot adds some spacing as a side effect. But the amount of spacing is independent from the amount of expansion.

  • Expanding the scale does what it does: It expands the y scale of the (basis) side plot, i.e. using expand=c(10, 0) we get an almost flat line as a result.

library(ggplot2)
library(ggside)
library(patchwork)

p1 <- base +
  scale_y_continuous(
    expand = c(0, 0),
    position = "right"
  ) +
  ggside(x.pos = "top", y.pos = "left") +
  labs(
    title = "expand = default"
    )

p2 <- p1 + 
  scale_xsidey_continuous(expand = c(.1, 0)) +
  labs(title = "expand = .1")

p3 <- p1 + 
  scale_xsidey_continuous(expand = c(10, 0)) +
  labs(title = "expand = 10")
  

p1 + p2 + p3

enter image description here

I checked out the docs and the ggside source code but have not found any option to increase the spacing. One option to get more control would be to create your side plots as separate plots and glue them together using patchwork. As an example of this approach see e.g. my answers on this post or this one.

If you want to stick with ggside I can only come up with a hacky workaround which uses a duplicated scale to add some spacing via the axis ticks. One drawback of this approach: It adds the spacing or margin on either side of the side plot (which makes me guess that this is the source of the aforementioned "bug" or side effect).

base +
  scale_y_continuous(
    expand = c(0, 0),
    position = "left",
    # Add a duplicated axis on the main plot
    sec.axis = dup_axis()
  ) +
  ggside(x.pos = "top", y.pos = "right") +
  # Remove the duplicated axis expect for the tick length to some spacing
  theme(
    axis.ticks.length.y.right = unit(20, "pt"),
    axis.ticks.y.right = element_blank(),
    axis.text.y.right = element_blank(),
    axis.title.y.right = element_blank()
  )

enter image description here

Base plot

base <- ggplot(df.1, aes(x = x, y = y)) +
  geom_contour(aes(z = z, color = after_stat(level))) +
  labs(
    x = expression(tilde(nu)[1] / cm^{
      -1
    }), y = expression(tilde(nu)[2] / cm^{
      -1
    })
  ) +
  scale_x_continuous(
    expand = c(0, 0)
  ) +
  theme(
    plot.tag.position = c(0.05, 0.95),
    legend.position = "bottom",
    legend.direction = "horizontal",
    legend.key.size = unit(0.5, "cm"),
    legend.key.width = unit(2, "cm"),
    aspect.ratio = 1
  ) +
  geom_xsideline(
    data = df.2, aes(x = x, y = y.1)
  ) +
  geom_ysideline(
    data = df.2, aes(x = y.2, y = x), orientation = "y"
  ) +
  theme(
    ggside.panel.scale = 0.125,
    ggside.axis.text = element_blank(),
    ggside.axis.ticks = element_blank()
  ) +
  guides(color = "none")

Upvotes: 1

Related Questions