Comments (15)
Thanks for trying that Albert. It looks to me as though the spacing is being increased between letters in the pdf version until you specify "family". Ultimately, both versions are drawn with the same font using grid::textGrob
- I'm guessing that the pdf device has a different fallback font when the "family" is left blank. We'll need to investigate this further, along with the vjust issue.
Thanks again
from geomtextpath.
Thanks! That narrows it down to a particular part of the code.
from geomtextpath.
Is this perhaps a problem with textshaping::shape_text
not respecting vjust on some machines?
@albert-ying -In a fresh R session with your normal default settings, the following function will return the value of the y offset (in pixels) for different values of vjust, given default font values:
f <- function(x) textshaping::shape_text('x', vjust = x)$shape$y_offset
For example, I get
f(0)
#> [1] 0
f(0.5)
#> [1] -5.421875
The symptoms you describe suggest that there is a problem with textshaping::shape_text
(or the arguments passed to it) that would result in this function returning 0 (or some other low, but fixed, number) for any input.
If I am right about this, then it suggests that on your system, every glyph height is somehow being measured as 0. This would happen, for example, if you passed a font size of 0, or if your device height was 0. We know that the font size is not 0, since the x measurements are correct. The most likely cause I can see for this is that the device height is somehow being registered as 0 in the textshaping::shape_text
function, but only if the f()
function above returns 0 for all numeric inputs.
from geomtextpath.
Hi @albert-ying. Thanks for using the package, and bringing this to our attention. It's not clear to me why this bug would show up on one system and not another. I'm assuming you have tried a new R session and the latest development version of geomtextpath
?
If so, would you mind checking the behaviour of a slightly modified version of the code so that we can try to track this down? If you modify the function to
plot_vjust <- function(vjust) {
ggplot(df, aes(x, y)) +
geom_textpath(aes(label = label, vjust = vjust)) +
geom_text(x = 2, y = 1, label = "geom_text", vjust = vjust) +
ggtitle(paste0("vjust = ", vjust)) +
scale_x_continuous(limits = c(-1, 3)) +
scale_vjust_identity()
}
Do you still get the same behaviour?
from geomtextpath.
I'm assuming you have tried a new R session and the latest development version of
geomtextpath
Yes.
I tried your modified code, it gives me the same result.
I noticed that when I save the plot as PDF, it gives the weird-looking font
Might be related to the rendering of the text/font?
update
The font looks normal after I specify the family
, but the vjust
still doesn't work. Also doesn't relate to the rich
argument.
geom_textpath(aes(label = label, vjust = vjust), rich = T, family = "Helvetica")
from geomtextpath.
Not just vjust
, \n
doesn't work here either, which is strange.
Thank you for looking at it!
library(ggplot2)
library(geomtextpath)
library(patchwork)
df <- data.frame(
x = seq(-0.5, 1.5, length.out = 10),
y = 1,
label = "geom_textpath \n 2nd row"
)
plot_vjust <- function(vjust) {
ggplot(df, aes(x, y)) +
geom_textpath(aes(label = label, vjust = vjust), family = "Helvetica") +
geom_text(x = 2, y = 1, label = "geom_text \n 2nd row", vjust = vjust) +
ggtitle(paste0("vjust = ", vjust)) +
scale_x_continuous(limits = c(-1, 3)) +
scale_vjust_identity()
}
p = plot_vjust(-1) + plot_vjust(0) + plot_vjust(1) + plot_vjust(2) + plot_vjust(10) + plot_vjust(15)
from geomtextpath.
Strange, I get the following on Linux, where the textpath does seem responsive to vjust
. My R version is 4.0.5 and linux distro is Ubuntu 20.04.3.
library(ggplot2)
library(geomtextpath)
library(patchwork)
df <- data.frame(
x = seq(-0.5, 1.5, length.out = 10),
y = 1,
label = "geom_textpath"
)
plot_vjust <- function(vjust) {
ggplot(df, aes(x, y)) +
geom_textpath(aes(label = label), vjust = vjust) +
annotate(x = 2, y = 1, label = "geom_text", geom = "text", vjust = vjust) +
ggtitle(paste0("vjust = ", vjust)) +
scale_x_continuous(limits = c(-1, 3))
}
p = plot_vjust(-1) + plot_vjust(0) + plot_vjust(1) + plot_vjust(2) + plot_vjust(10) + plot_vjust(15)
p
Created on 2022-01-13 by the reprex package (v2.0.0)
But something seems off about vjust anyhow, it doesn't quite follow the vanilla text offsets. The text spacing looks weird as well. Update: text spacing issue seems device dependent (doesn't appear when using ragg).
from geomtextpath.
Hmm I'm on R 4.1.1, Ubuntuk 16.04.6.
Is there any system-related dependency that might be related to this?
from geomtextpath.
I'm not aware that we'd have such dependencies, we don't have any compiled code in geomtextpath.
I'm sorry we can't debug this ourselves, we don't have the same platform setup as you do. Would you mind checking for me what the following code returns in your case?
geomtextpath:::measure_label("AB\nCD")[[1]]
#> glyph ymin xmin xmid xmax substring y_id
#> 1 A 0.1116536 0.009331597 0.06488715 0.1204427 1 2
#> 2 B 0.1116536 0.120442708 0.17599826 0.2315538 1 2
#> 3 C -0.1116536 0.000000000 0.06011285 0.1202257 1 3
#> 4 D -0.1116536 0.120442708 0.18055556 0.2406684 1 3
Created on 2022-01-13 by the reprex package (v2.0.1)
The exact values can vary slightly due to the fonts available (this was Arial on windows), but I'm interested to see if the ymin
column varies, in which case we can rule out that textshaping is giving weird results.
from geomtextpath.
I have tracked down part of the problem. You'll notice that the geomtextpath position is wrong when vjust == 1. This is actually due to a bug in one of the dependencies (textshaping), which gives the wrong y position when vjust is exactly 1:
textshaping::shape_text('hello', vjust = 1)
#> $shape
#> # A tibble: 5 x 7
#> glyph index metric_id string_id x_offset y_offset x_midpoint
#> <int> <int> <int> <int> <dbl> <dbl> <dbl>
#> 1 0 75 1 1 0 0 3.33
#> 2 1 72 1 1 6.67 0 3.33
#> 3 2 79 1 1 13.3 0 1.33
#> 4 3 79 1 1 16.0 0 1.33
#> 5 4 82 1 1 18.7 0 3.33
#>
#> $metrics
#> # A tibble: 1 x 11
#> string width height left_bearing right_bearing top_bearing bottom_bearing
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 hello 25.4 24.3 0.797 0.438 2.27 2.41
#> # ... with 4 more variables: left_border <dbl>, top_border <dbl>, pen_x <dbl>,
#> # pen_y <dbl>
textshaping::shape_text('hello', vjust = 1 + .Machine$double.eps)
#> $shape
#> # A tibble: 5 x 7
#> glyph index metric_id string_id x_offset y_offset x_midpoint
#> <int> <int> <int> <int> <dbl> <dbl> <dbl>
#> 1 0 75 1 1 0 -10.9 3.33
#> 2 1 72 1 1 6.67 -10.9 3.33
#> 3 2 79 1 1 13.3 -10.9 1.33
#> 4 3 79 1 1 16.0 -10.9 1.33
#> 5 4 82 1 1 18.7 -10.9 3.33
#>
#> $metrics
#> # A tibble: 1 x 11
#> string width height left_bearing right_bearing top_bearing bottom_bearing
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 hello 25.4 24.3 0.797 0.438 2.27 2.41
#> # ... with 4 more variables: left_border <dbl>, top_border <dbl>, pen_x <dbl>,
#> # pen_y <dbl>
textshaping::shape_text('hello', vjust = 1 - .Machine$double.eps)
#> $shape
#> # A tibble: 5 x 7
#> glyph index metric_id string_id x_offset y_offset x_midpoint
#> <int> <int> <int> <int> <dbl> <dbl> <dbl>
#> 1 0 75 1 1 0 -10.8 3.33
#> 2 1 72 1 1 6.67 -10.8 3.33
#> 3 2 79 1 1 13.3 -10.8 1.33
#> 4 3 79 1 1 16.0 -10.8 1.33
#> 5 4 82 1 1 18.7 -10.8 3.33
#>
#> $metrics
#> # A tibble: 1 x 11
#> string width height left_bearing right_bearing top_bearing bottom_bearing
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 hello 25.4 24.3 0.797 0.438 2.27 2.41
#> # ... with 4 more variables: left_border <dbl>, top_border <dbl>, pen_x <dbl>,
#> # pen_y <dbl>
I'm guessing that the bug is further-reaching on some systems?
Created on 2022-01-13 by the reprex package (v2.0.1)
from geomtextpath.
Yeah I defensively coded against that bug previously:
Lines 44 to 45 in 616d6b5
But this I forgot to catch that bug when I refactored the code at some point. I've already included it in my local version, so it'll be fixed after the next PR. AFAIK, it shouldn't affect any other vjust values.
from geomtextpath.
Here is my output, the ymin indeed does not vary
geomtextpath:::measure_label("AB\nCD")[[1]]
glyph ymin xmin xmid xmax substring y_id
1 A 0.07736545 0.008029514 0.06488715 0.1217448 1 2
2 B 0.07736545 0.121961806 0.17903646 0.2361111 1 2
3 C 0.07736545 0.000000000 0.05815972 0.1163194 1 2
4 D 0.07736545 0.116319444 0.18033854 0.2443576 1 2
from geomtextpath.
Yes, you are right! @AllanCameron
[ins] r$> f <- function(x) textshaping::shape_text('x', vjust = x)$shape$y_offset
[ins] r$> f(0)
[1] 0
[ins] r$> f(0.5)
[1] 0
from geomtextpath.
Thanks for trying that @albert-ying
From looking at the shape_text
source code, it is really just an R wrapper round HarfBuzz, which is written in c++. I can't see anything in the shape_text
source that should be affected by the system you are using, so my guess would be that there is some issue with HarfBuzz, which builds differently according to the system on which it is compiled. You will already have this installed on your computer, but I think that if you were able to update this package, maybe here, this may fix your problem.
from geomtextpath.
Thank you for helping and figuring out the root cause! Although I failed to link the new version of HarfBuzz to shape_text
... But it is not the problem of geomtextpath
anymore, I think. Still nice to know what is happing under the hood, thank you so much!
from geomtextpath.
Related Issues (20)
- Long labels with arrow throw cryptic "Error: Cannot create zero-length unit vector ("unit" subsetting)" error
- Strange behaviour of halign HOT 4
- Feature Request: Set angle for geom_labelvline HOT 6
- Feature request - test for text self-overlap on sharp contours HOT 1
- ggplot coord_polar() issue with multiple classes: 'from' must be a finite number error HOT 1
- session aborted when library in Rstudio HOT 2
- text_only in geom_labelsegment
- Feature request - avoid text overlapping
- two labels on same curve HOT 5
- straight argument unknown in geom_textsf() HOT 2
- `label` aesthetic in `geom_textdensity2d` HOT 2
- R 4.3.0 and glyphs 👀 HOT 1
- Can't get things to work HOT 11
- vjust and hjust as aesthetics in geom_textsf HOT 3
- Different behavior for line breaks when there's no data
- geomtextline not accommodating RGBA colors
- show.legend not working in geom_textabline
- Support for `geom_step()`? HOT 2
- Partial match of 'xoff' to 'xoffset'
- geom_textsf seems to ignore remove_long=F
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from geomtextpath.