0

Have a look at the following plot:

ggplot(mtcars, aes(x = mpg, y = wt)) + 
  geom_point() + 
  geom_hline(yintercept = 3) + 
  theme(axis.title.x = element_text(vjust = 85))

enter image description here

As you can notice, the x-axis title has been shifted and is located just below the horizontal line.

My current plot window dimensions are 17.38312 x 16.98625 cm. If I change them to smaller ones (e.g. 12.88521 x 11.08604 cm), then the plot looks like this:

enter image description here

So as you can see, the title is no longer in the same position, now it's above the horizontal line. If we make the plot larger (24.15646 x 20.32000 cm), then the title is much below the horizontal line.

enter image description here

I tried using coord_fixed(), but that didn't seem to be intended for these types of problems.

How can I ensure that when I am using hjust and vjust I am not moving the text in some absolute units, but rather in relative terms of the graph width/height, so that the text always remains in the same position when I resize the graph?

J. Doe
  • 1,544
  • 1
  • 11
  • 26
  • 2
    I doubt this is possible with `vjust`, which is intended to justify text relative to the outside boundaries of that text (e.g. `hjust` is 0 for left-aligned, 1 for right-aligned). The text size (relative to the plot) obviously changes as you resize your window, so this is never going to work. You would be better off placing the label with `geom_text` or `annotate`. – Andrew Gustar Apr 30 '23 at 14:46
  • Are you trying to add the text immediately below the hline, or is it at a proportion of the screen plot region dimensions? – r2evans Apr 30 '23 at 14:53
  • @r2evans I am not sure how these are two different things. – J. Doe Apr 30 '23 at 15:15
  • 1
    `vjust` is always relative to the string's _height_; `hjust` is always relative to the string's _width_; neither of those is relative to the plotting region, and cannot be warped into being so. If you want the text always plotted at a relative position in the plotting region, `hjust` and `vjust` are not your tools. – r2evans Apr 30 '23 at 15:37
  • 2
    You can get what I think you want by removing your `theme(.)` and adding `+ geom_text(data = ~ with(., data.frame(mpg = mean(range(mpg)), wt = 3)), label = "mpg", vjust = 1.1) + scale_x_continuous(name = NULL)`. – r2evans Apr 30 '23 at 16:52
  • OP, what is your desired output here? If you want to put text into the plot area, moving the axis title text is just about the worst way I can think of doing it (and is almost guaranteed to be inconsistent) – chemdork123 Apr 30 '23 at 19:33
  • @chemdork123 The purpose is to pretend that the hline is actually the x-axis line and then have the title of the axis below it – J. Doe Apr 30 '23 at 19:36
  • I would suggest [this answer](https://stackoverflow.com/a/73566140/9664796) could be useful. If `geom_hline()` here represents your x axis, there's some nice formatting from the `ggh4x` package. – chemdork123 Apr 30 '23 at 21:32

2 Answers2

1

Another option is to use the geomtextpath package, which offers the possibility to add a label to a line, in this case a hline. you can then modify the relative label position with a vjust to your liking.

> library(geomtextpath)
Loading required package: ggplot2
> 
> ggplot(mtcars, aes(x = mpg, y = wt)) + 
+   geom_point() + 
+   geom_texthline(yintercept = 3, vjust = 1.5, label = "mpg")

Figure dimensions 2x3 inches

Figure dimensions 3x3 inches

Created on 2023-04-30 with reprex v2.0.2

tjebo
  • 21,977
  • 7
  • 58
  • 94
0

I think the problem will be solved if you fix the plot size and save different plots with the same dimension. Also, the geom_text is a better choice for resizing. Other options such as geom_text_repel and geom_label_repel from ggrepel package and geom_label_interactive from ggiraph are also available. Kindly ignore the irrelevant example below and re-write the codes if it is useful.

library(ggplot2)
library(ggiraph)
library(ggrepel)
df <- data.frame(x=1:5, y=1:5, text=LETTERS[1:5])

ggplot(df, aes(x, y)) +
  geom_text(aes(label = text))+
  labs(title='using geom_text')
ggsave('file1.jpg', height = 24, width = 20, units = 'cm')

enter image description here

ggplot(df, aes(x, y)) +
  geom_text_repel(aes(label = text))+
  labs(title='using geom_text_repel')
ggsave('file2.jpg', height = 24, width = 20, units = 'cm')

enter image description here

ggplot(df, aes(x, y)) +
  geom_label_repel(aes(label = text))+
  labs(title='using geom_label_repel')
ggsave('file3.jpg', height = 24, width = 20, units = 'cm')

enter image description here

ggplot(df, aes(x, y, label = text)) +
  geom_label_interactive(aes(tooltip = text))+
  labs(title='using geom_label_interactive')
ggsave('file4.jpg', height = 24, width = 20, units = 'cm')

enter image description here I hope it helps.

Afshin
  • 103
  • 6