Giter Club home page Giter Club logo

Comments (14)

teunbrand avatar teunbrand commented on July 24, 2024

Hi Allan, yes looks like a good addition to the package. Putting the labels on a curve looks much more elegant that the default labelling. One thing to keep in mind is that if we introduce an element_textpath(), it is unclear whether it should be a stand-in for element_line() or element_text() and I think people expect that it would work anywhere, not just in this coord function.

from geomtextpath.

AllanCameron avatar AllanCameron commented on July 24, 2024

I think it would be nice if we could use an element_textpath as a substitution for element_text, and I think it should be possible to get this to work. It might be a challenge to get it to work as demonstrated above as purely an element without the need for a whole new coord, but it would be nice if we could.

One of the difficulties is that the textpathGrob needs to be passed path data, and of course element_text only contains single points. It is possible to create a simple horizontal path from these points inside element_grob.element_textpath, but in polar co-ordinates this step has to occur after the polar transformation, so we need to calculate the correct circular path. If the co-ordinates aren't polar, this creates some funky results. If we can get element_grob.element_textpath to be know the co-ordinate system, then there's no reason why we can't have element_textpath as a drop-in for element_text

from geomtextpath.

teunbrand avatar teunbrand commented on July 24, 2024

I'm pretty confident that we can get element_textpath() to work, instead, the point I'm raising is whether we should. If it is for a single use case such as coord_curvedpolar(), it is a bit of a burden on users to have to recall that it should not be element_text() and that the axis text in this particular coord has a different theme element that controls the axis text. If there is a more general case to use it, then yes we should go for it. We can internally use the result of calc_element("axis.text.{x/y}", theme) to populate the text parameters and not go through element_grob(), but construct the textpath ourselves (I'm presuming in this case we don't have a path component to render as well). I think it would be nice if + theme(axis.text.{x/y} = element_text(colour = "blue")) would just work out of the box.

from geomtextpath.

AllanCameron avatar AllanCameron commented on July 24, 2024

That sounds like a good plan. I did not know about calc_element. Presumably we can use this in the draw_fg member function to convert the element_text parameters into appropriate arguments for the textpathGrob. I will try this approach.

from geomtextpath.

AllanCameron avatar AllanCameron commented on July 24, 2024

OK, so I managed to put everything inside the render_fg function, including your trick of harvesting the gpars from element_text. The only slight snag is that halign isn't a parameter within element_text, and has to be passed as a parameter of the coord_curvedpolar function itself. This is only relevant for multi-line axis labels anyway, which should be pretty uncommon.

The amazing thing is how easy all this is to implement now that we have a solid textpathGrob

The current behavior is this:

library(geomtextpath)
#> Loading required package: ggplot2

p <- ggplot(data.frame(x = paste("Category label", 1:5), y = runif(5)), 
            aes(x, y, fill = x)) +
       geom_col() +
       theme_bw() +
       theme(panel.border = element_blank(),
             legend.position = "none", 
             axis.text.x = element_text(size = 10, vjust = 0.5))

p 

p + coord_polar()

p + coord_curvedpolar()

p + coord_curvedpolar() + 
  theme(axis.text.x = element_text(color = "red4", size = 15, hjust = 1))

Unfortunately reprex::reprex() is pretty ugly at rendering, particularly with curved text. I should be able to add a much nicer example to the readme.

Created on 2021-11-29 by the reprex package (v2.0.0)

from geomtextpath.

teunbrand avatar teunbrand commented on July 24, 2024

Very nice work Allan! I think with all the nice examples and this new function, we could dedicate a separate vignette to curved text in polar coordinates. I'll play around with this later this evening to see how it works, I'll admit I'm not very well acquainted with coord internals. The third plot looks very good, but in the 4th plot the hjust confuses me (but after double checking indeed seems correct).

from geomtextpath.

AllanCameron avatar AllanCameron commented on July 24, 2024

My impression from reading the docs and the internals is that Hadley doesn't like polar plots very much. I understand his reluctance, but I do think they have a place. It almost feels like coord_polar has been implemented grudgingly. The theta axis that we change here is actually just drawn as a foreground layer that calculates some grobs. I have lifted most of the code from CoordPolar, and only changed which grobs are drawn.

I don't think the hjust and vjust are correct at the moment. I think this is because of the direction that the supporting segments are drawn in. Hopefully this is an easy fix.

from geomtextpath.

AllanCameron avatar AllanCameron commented on July 24, 2024

Ah, I think I've found a problem. The vjust flips when flip_inverted is TRUE, which I don't think is the correct behaviour (and actually makes it much harder to have vjust - able axis labels. I will submit a fix for this.

library(geomtextpath)
#> Loading required package: ggplot2

df <- data.frame(x = c(1, 0, 0, 1), y = c(2, 2, 1, 1), 
                 z = rep(c("This text has been inverted", "This text hasn't"),
                           each = 2))

ggplot(df, aes(x, y, group = z)) + 
  geom_textpath(aes(label = z), size = 8, vjust = 1, flip_inverted = FALSE) +
  lims(y = c(0, 3))

ggplot(df, aes(x, y, group = z)) + 
  geom_textpath(aes(label = z), size = 8, vjust = 1, flip_inverted = TRUE) +
  lims(y = c(0, 3))

In the second image above, although I would expect text to be the right way up, I would expect it to remain above the line.

Created on 2021-11-29 by the reprex package (v2.0.0)

from geomtextpath.

teunbrand avatar teunbrand commented on July 24, 2024

Right yes, that makes sense. I think it might just be as easy as to add this:

attr(label, "offset") <- 0 - attr(label, "offset")

to the following lines:

path <- path[rev(seq_len(nrow(path))), ]
hjust <- 1 - hjust
.get_path_points(
path, label, hjust, halign,
flip_inverted = FALSE
)

from geomtextpath.

AllanCameron avatar AllanCameron commented on July 24, 2024

OK, I'll try that...

...yes. That did the trick. A positive vjust now pushes all the text radially outwards.

p + coord_curvedpolar() + theme(axis.text.x = element_text(vjust = -1))

image

And the hjust is correct, as long as you remember that the bottom strings have been flipped so seem to have an hjust of 1.

p + coord_curvedpolar() + theme(axis.text.x = element_text(hjust = 0))

image

It might be logical not to flip the hjust for this reason.

from geomtextpath.

AllanCameron avatar AllanCameron commented on July 24, 2024

Incidentally, there is a problem in calculating the surrounding lines when text is flipped, independently of the problem above. In the latest branch we have:

library(geomtextpath)
#> Loading required package: ggplot2

df <- data.frame(x = c(1, 0, 0, 1), y = c(2, 2, 1, 1), 
                 z = rep(c("This text has been inverted", "This text hasn't"),
                           each = 2))

ggplot(df, aes(x, y, group = z)) + 
  geom_textpath(aes(label = z), size = 8, hjust = 1, flip_inverted = FALSE) +
  lims(y = c(0, 3))

ggplot(df, aes(x, y, group = z)) + 
  geom_textpath(aes(label = z), size = 8, hjust = 1, flip_inverted = TRUE) +
  lims(y = c(0, 3))

Created on 2021-11-29 by the reprex package (v2.0.0)

from geomtextpath.

teunbrand avatar teunbrand commented on July 24, 2024

Should we just avoid flipping hjust then, if flipping it can give these weird results? Or should we defensively code against these cases? Is there a case where flipping hjust is sensible?

from geomtextpath.

AllanCameron avatar AllanCameron commented on July 24, 2024

If you remove the hjust flip, the surrounding line flips too, so the text still gets scored out, but on the other side.

from geomtextpath.

teunbrand avatar teunbrand commented on July 24, 2024

Right yes, you're correct. I found a 2-line fix for this, I'll include in the next PR.

from geomtextpath.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.