Comments (7)
Yes I think it very much makes sense to do this. We'd have to make it clear in the docs, readme and possibly introduction vignette that this is the behaviour to be expected. But this raises the question whether point-textpath (sounds like a paradox), should support an angle
aesthetic or always be plotted horizontally (in Cartesian coordinates). At the moment I'm in favour of no angle
aesthetic, as it's ambiguous what that would imply for path-textpaths, but I can be persuaded otherwise.
I'm also curious how the small path would be calculated, because if you draw it too long, the hjust
will be off and if you draw it too short it might not curve properly in polar coordinates. I'm presuming here that the path extension happens at the ggproto level before grob construction, to take advantage of the polar transformation (if applicable).
from geomtextpath.
Yes, this code is inside the draw_panel
of geom_textpath
At the moment I am calculating the little path from the string width (taken from shape_string). It needs to be at least as long as the text string, otherwise the curvature doesn't work. I have also changed all linetypes to 0, since we assume that in this case the user doesn't need to know about the path.
You're right that this makes hjust
useless. We can address in a few different ways:
- Use the
hjust
to recalculate the little path. - Make the little path twice the string length. This would allow
hjust
to work in the [0, 1] range. - Simply tell people that
hjust
won't work in this scenario
Personally, I quite like number 2.
It wouldn't be difficult to implement angle aesthetic for the "point textpaths", and I actually quite like the idea. However, I agree that it doesn't make sense for "path textpaths". Since we are already detecting which of the two is intended by the user, I don't see a problem with implementing it only for point-textpaths. We should be able to warn users that angle will be ignored for "path textpaths", but only where angle is specifically passed as a parameter.
from geomtextpath.
I have also changed all linetypes to 0
For the point-texpaths that makes perfect sense.
At the moment I am calculating the little path from the string width (taken from shape_string)
I'm not saying this won't work, but from a theoretical perspective, this returns metrics in pixels, which at draw_panel
time still has an unknown relation with the NPC units that the data begets after coord transformation.
Use the hjust to recalculate the little path.
That would probably be the nicest for users, I've sketched a small function for this (y-axis == hjust).
x <- c(1,1,1)
y <- c(0, 0.5, 1)
small_path <- function(x, y, angle, width, hjust) {
angle <- angle / 180 * pi
xmin <- x + cos(angle + pi) * width * hjust
xmax <- x + cos(angle) * width * (1 - hjust)
ymin <- y + sin(angle + pi) * width * hjust
ymax <- y + sin(angle) * width * (1 - hjust)
data.frame(xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax)
}
path <- small_path(x, y, 0, 2, hjust = y)
plot(x, y, xlim = c(-1, 3), ylim = c(-0.5, 1.5))
segments(path$xmin, path$ymin, path$xmax, path$ymax)
# Change angle
path <- small_path(x, y, 45, 2, hjust = c(0, 0.5, 1))
plot(x, y, xlim = c(-1, 3), ylim = c(-0.5, 1.5))
segments(path$xmin, path$ymin, path$xmax, path$ymax)
Created on 2021-11-30 by the reprex package (v2.0.1)
from geomtextpath.
Actually, I don't think it's possible to hack the hjust from within draw_panel
because of the whole makeContent
mechanism. The length of the text string relative to the path changes according to the device size, so if we grow the device, the little path will get bigger while the text remains the same size. This would have the effect of multiplying the hjust by the same proportion as the device size is multiplied.
from geomtextpath.
I'll push the commit anyway, since it seems to be a desirable feature, and we can work out how (or if) we handle hjust with "point textpaths" once we have had more of a play with it. If we feel the hjust is vital we can consider handling it inside makeContent
from geomtextpath.
I have implemented the angles for point-like textpaths inside draw_panel
. Again, these don't behave quite the same as geom_text
because the angle is changed as they are scaled. The angle is only accurate with coord_equal
(although it should therefore always be accurate in polar coords). I think if we decide this is a bug rather than a feature (I'm not sure about that), it would have to be moved into the makeContent
part.
Anyway, the current behaviour is this:
library(geomtextpath)
#> Loading required package: ggplot2
pie <- data.frame(values = c(5, 4, 2.5),
mids = c(2.5, 7, 10.25),
fruit = c("banana", "orange", "apple"),
colour = c("yellow", "orange", "green"),
x = 1)
p <- ggplot(pie, aes(x = x, y = mids, label = fruit)) +
geom_col(aes(x = x, y = values, fill = colour)) +
scale_fill_identity() +
theme_void()
p_00 <- p + geom_textpath(size = 8, flip_inverted = TRUE, angle = 0)
p_90 <- p + geom_textpath(size = 8, flip_inverted = TRUE, angle = 90)
p_45 <- p + geom_textpath(size = 8, flip_inverted = TRUE, angle = 45)
p_00
p_00 + coord_polar(theta = "y")
p_90
p_90 + coord_polar(theta = "y")
p_45
p_45 + coord_polar(theta = "y")
Created on 2021-11-30 by the reprex package (v2.0.0)
from geomtextpath.
Right. I think I've cracked this. I wasn't happy with the little paths and angles being outside of makeContent
, so I've moved them inside. Now the angle parameter behaves as expected (in line with geom_text
), as does the hjust
. It does mean that the textpathGrob
now takes 2 new parameters - angles and a switch for telling it to produce little polar paths instead of little straight paths. It also nearly melted my brain to produce little angled paths in polar co-ordinates.
All that aside, I'm very pleased with the results:
library(geomtextpath)
#> Loading required package: ggplot2
pie <- data.frame(values = c(5, 4, 2.5),
mids = c(2.5, 7, 10.25),
fruit = c("banana", "orange", "apple"),
colour = c("yellow", "orange", "green"),
x = 1)
p <- ggplot(pie, aes(x = x, y = mids, label = fruit)) +
geom_col(aes(x = x, y = values, fill = colour)) +
geom_point() +
scale_fill_identity() +
theme_void()
p + geom_textpath(size = 8, flip_inverted = TRUE, angle = 0, hjust = 0)
p + geom_textpath(size = 8, flip_inverted = TRUE, angle = 0, hjust = 1)
p + geom_textpath(size = 8, flip_inverted = TRUE, angle = 0, hjust = 1) +
coord_polar(theta = "y")
p + geom_textpath(size = 8, flip_inverted = TRUE, angle = 45, hjust = 0)
p + geom_textpath(size = 8, flip_inverted = TRUE, angle = 45, hjust = 1)
p + geom_textpath(size = 8, flip_inverted = TRUE, angle = 45, hjust = 1) +
coord_polar(theta = "y")
p + geom_textpath(size = 8, flip_inverted = TRUE, angle = 90, hjust = 0)
p + geom_textpath(size = 8, flip_inverted = TRUE, angle = 90, hjust = 1)
p + geom_textpath(size = 8, flip_inverted = TRUE, angle = 90, hjust = 1) +
coord_polar(theta = "y")
Created on 2021-11-30 by the reprex package (v2.0.0)
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
- Add compatibility with `ggbump` HOT 2
- geom_textsf randomly throws erros when specification of font family is missing (OpenSUSE Leap 15.5, R 4.3.2) HOT 2
- 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.