Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NF - Text numeric values for ha and va #1181

Closed
wants to merge 1 commit into from
Closed

NF - Text numeric values for ha and va #1181

wants to merge 1 commit into from

Conversation

2sn
Copy link

@2sn 2sn commented Aug 31, 2012

Hi,

I added a quick patch to allow numerical values for text alignment.
It now allows a number that is fraction of text hight or with and is measured relative to bottom or left. So
ha = 0 == 'left'
ha = 1 == 'right'
va = 0 == 'bottom'
va = 1 == 'top'
va/ha = 0.5 == 'center'

the cool thing is that values outside [0,1] allow you to some defined distance from a line or symbol that remains well-measured even if you interactively scale the figure.

Can you please add this to MPL?

(also fixed some typos in typo doc)

OK, I try this pull request, I hope this is OK and I don't bother not too many people by maybe doing this somewhat out of line.

-Alexander

@travisbot
Copy link

This pull request fails (merged dd661b9 into cf7618c).

@2sn
Copy link
Author

2sn commented Sep 3, 2012

It says "This pull request fails". Not sure what fails. Seems to be some difference in produced figures that is not due to my pull request. Since I do this for the the first time, could anybody have a look and help to track this down? -Alexander

@efiring
Copy link
Member

efiring commented Sep 3, 2012

Based on a very quick look, I don't think the failures have anything to do with your changes.

@2sn
Copy link
Author

2sn commented Sep 3, 2012

Thanks. Maybe some one still wants to do some testing, but it is simple and straight forward enough to see what this does and that is should be OK. The only thing may be if someone wanted to add some extra checks. For example, I only check for numbers using is_numlike(), but is_numlike(np.array([1,1])) also returns true but would make the code fail. I guess I could add to require size() == 1. Should this be done?

@pwuertz
Copy link
Contributor

pwuertz commented Sep 3, 2012

I don't like this idea because of two reasons.

It contradicts the idea of being able to anchor text elements in vector output formats #1081. I think the definition of text properties should follow a common consensus that exists throughout various toolkits and formats, and I'm not sure that I've seen this way of text positioning anywhere else yet. Supporting such a definition will make anchoring harder.

Also I don't think that this definition is reasonable. Your idea is to have 'some defined distance from a line or symbol'. The distance you'll get however is completely undefined because it will change as the width and height of your text varies. Imagine 2 text elements being placed va=1.1 under a horizontal line. The one with the bigger height will be further away from the line.

The canonical way of doing this is to define attributes like margin-left, margin-right, margin-top, margin-bottom.

@2sn
Copy link
Author

2sn commented Sep 3, 2012

OK, I agree you have a good point about the size not being well defined. That would even affect my use case.

In some other cases, however, this could be what is desired, say you wanted to align 30% from the bottom for a given text - in this case a fixed 'margin' would not work. So, this solution is not perfect, but it add something w/o removing anything. For the relative size of displacement outside depending of the text string, you would have to take care of this manually. Possible concepts would be size units as in LaTeX 'em'. But just points would seem ideal to me. Then the question is whether to measure w/r the base line or the top. Even the current implementation with 'top' aliment - it I used it on 'o' or 'O', say both below a given horizontal line, they would have different base lines and that would look ugly. So you would want to have a 'font upper bound' for use instead?

BTW, I don't see any 'margin' in the Text definition, is there?

Hmm, relative alignment with the text, i.e., 0...1, may still be useful?

For distances along the 'margin' idea one would have to agree on a unit - I recommend points to be consistent with symbol size definitions - and a reference point. Not sure how to get these, though. Default could be 'baseline', but 'top' and 'bottom', maybe 'center' could be useful as well. I does require extra parameters - horizontal_offset and vertical_offset relative to the reference point. Would that be a better solution? And most of all, an acceptable solution? (I do need a solution, the current fix may be too simple, but at least gets one part-ways there, so it could be added until some one has a better one, or we agree on a better one, I am happy to work on it if there is an agreement what to do.)

-Alexander

@2sn
Copy link
Author

2sn commented Sep 3, 2012

OK, I still think keeping the numerical number as implemented can be useful to allow flexible anchoring relative to the actual size of the text, not just 'top', 'bottom', etc.

I agree with pwuertz something else needs to be done. Not sure the margin-x would work as it leaves open the question of aliment. Unless margin-* implies alignment w/r that same, which could be confusing. I propose to keep the ha/va, add the numeric values as I have done, and then add an 'offset' keyword (horizonatloffset/ho and verticaloffset/vo). The question is the units. It should be a fixed unit w/r the font, e.g., points (as is also used for marker sizes - which is the purpose of the exercise to have fond at a fixed distance from the boundary of a marker symbol. So, in my case I could have

x,y= 0.5,0.5
plot(x,y,'bo',markersize=8)
t = Text(x,y,'X',ha='center',va='top',vo=6)
gca().a.add_artist(t)
draw()

(vo is to be added)

@2sn
Copy link
Author

2sn commented Sep 3, 2012

... another possible scale other than point could be font size from

prop.get_size_in_points()

@efiring efiring mentioned this pull request Jul 22, 2013
@tacaswell
Copy link
Member

@pwuertz @2sn It looks like the consensus (a year ago) was to not merge this so I am closing it. It can be reopened if I miss-understood.

@tacaswell tacaswell closed this Nov 26, 2013
@2sn
Copy link
Author

2sn commented Nov 26, 2013

it would just seem a straight-forward addition that does not interfere with
anything else.

I don't understand why this is an issue?
Because it was not an idea of the main developers?

I got very frustrated about adding things to matplotlib.
Attempts to contribute seem futile.

On Wed, Nov 27, 2013 at 4:47 AM, Thomas A Caswell
notifications@github.comwrote:

Closed #1181 #1181.


Reply to this email directly or view it on GitHubhttps://github.com//pull/1181
.

@tacaswell
Copy link
Member

@2sn I am sorry you feel that way.

It is not clear that this change does not interfere with anything, as @pwuertz says that this complicates dealing with text in vector backends. Due to the complication in properly laying out text it also makes sense to keep mpl's interface as close to the 'standard' properties interface as possible. I have also never seen text alignment specified this way.

You agreed that, as written, this has undefined behavior and would need to be modified. You suggested some alternates in the comments, but they did not go into the repo. After a year of no activity I assumed this was dead.

I would also suggest that there are alternate (and easier) ways to do what you want. The example usage you gave in your 3rd to last comment can be done with

x,y= 0.5,0.5
ax = gca()
ax.plot(x,y,'bo',markersize=8)
ax.annotate('X', xy=(x,y), xytext=(0, 6), textcoords='offset points', ha='center')

draw()

I think in most cases where you would want to use this functionality you would be better off moving the (x, y) location of the string.

@pwuertz
Copy link
Contributor

pwuertz commented Nov 27, 2013

I was about to say the exact same thing, thanks to @tacaswell I dont have to :).

@pelson
Copy link
Member

pelson commented Dec 5, 2013

@2sn - I just wanted to encourage you to continue making submissions to matplotlib. Matplotlib is a complex tool which no one person can know everything about (even @mdboom and the late, great @jdh2358). As such it is inevitable that for some PRs it will transpire that the change makes a certain facet harder or even impossible to maintain, as I believe was the case with this proposed change. Whilst I'm the first to admit that we are pretty slow at actually getting PRs merged (the order of several months is not unheard of), it is, IMHO, fairly rare that a proposed change doesn't actually make it into mpl in some form or another, and I can assure you that the diversity of contributors to matplotlib is one of the main reasons I love being involved with the project.

As I say, please don't be discouraged from discussing changes on the mailing list, or indeed submitting PRs - we are just trying to balance improving usability and functionality of matplotlib whilst still keeping it on the straight-and-narrow in a maintainable and extendible form.

Thanks to @tacaswell & @pwuertz for giving an honest and clear description of why this PR was rejected.

Cheers,

solvents pushed a commit to solvents/matplotlib that referenced this pull request Apr 19, 2014
…density is now referred to as gaussian_kde and exists as a class in mlab. Updated violinplot examples with up-to-date customization options
solvents pushed a commit to solvents/matplotlib that referenced this pull request Apr 21, 2014
…density is now referred to as gaussian_kde and exists as a class in mlab.

Fixed list comp position bug and updated examples
solvents pushed a commit to solvents/matplotlib that referenced this pull request Apr 22, 2014
…density is now referred to as gaussian_kde and exists as a class in mlab.

Fixed list comp position bug and updated examples
solvents pushed a commit to solvents/matplotlib that referenced this pull request Apr 22, 2014
…density is now referred to as gaussian_kde and exists as a class in mlab.

Fixed list comp position bug and updated examples
solvents pushed a commit to solvents/matplotlib that referenced this pull request Apr 23, 2014
…density is now referred to as gaussian_kde and exists as a class in mlab.

Fixed list comp position bug and updated examples
solvents pushed a commit to solvents/matplotlib that referenced this pull request May 16, 2014
…density is now referred to as gaussian_kde and exists as a class in mlab.

Fixed list comp position bug and updated examples
solvents pushed a commit to solvents/matplotlib that referenced this pull request May 24, 2014
…density is now referred to as gaussian_kde and exists as a class in mlab.

Fixed list comp position bug and updated examples
@has2k1
Copy link
Contributor

has2k1 commented Sep 6, 2015

Can this be resurrected? I can update (rebase/cherry-pick for proper attribution) it if possible.

Functionally, the strings 'left', 'right', 'top', 'bottom' and 'center' represent multiplicative factors. If the underlying factors are made available users may find it an acceptable solution whether a better
one exists or not.

For precedence, R has the textGrob which has parameters hjust and vjust that correspond to horizontalalignment and verticalalignment.

However hjust and vjust take numerical values, but at this level of plotting it is perhaps as easy to just alter the (x, y) position. Up the ladder, ggplot2 uses textGrob underneath for geom_text and hjust & vjust become aesthetics onto which you can map values. At this level while hjust & vjust can still be "misused" but they can also be a simpler solution than manipulating the (x, y) positions.

This is a good example. Also the last graph here is another example where because of the type of plot it was easier to fiddle with hjust values than to manipulate x values. There are many other examples where non-standard (other than 0, 0.5 and 1) factors are used.

These use cases would be very handy if available in ggplot for python which hinges on this PR.

@2sn
Copy link
Author

2sn commented Sep 8, 2015

Dear Hassan,

I use the alignment in graphs where the font has to be plotted relative
to some points depending on other factors. I just use my derived text
Class with this included - maybe slightly dated - but I could try to fix
this up including embedded help text and and a pull request if there is
genuine interest.

Obviously, it is a rather small change to the class.

Best wishes,
Alexander

On 06/09/15 11:58, Hassan Kibirige wrote:

Can this be resurrected? I can update (rebase/cherry-pick for proper
attribution) it if possible.

Functionally, the strings 'left', 'right', 'top', 'bottom' and 'center'
represent multiplicative factors. If the underlying factors are made
available users may find it an acceptable solution whether a better
one exists or not.

For precedence, |R| has the |textGrob|
http://www.inside-r.org/r-doc/grid/textGrob which has parameters
|hjust| and |vjust| that correspond to |horizontalalignment| and
|verticalalignment|.

However |hjust| and |vjust| take numerical values, but at this level of
plotting it is perhaps as easy to just alter the |(x, y)| position. Up
the ladder, ggplot2 uses |textGrob| underneath for |geom_text|
http://docs.ggplot2.org/current/geom_text.html and |hjust| & |vjust|
become aesthetics onto which you can map values. At this level while
|hjust| & |vjust| can still be "misused" they can also be simpler
solution than manipulating the |(x, y)| positions.

This http://stackoverflow.com/a/24627761 is a good example. Also the
last graph here http://redheadedstepdata.io/large-weather-events/ is
another example where because of the type of plot it was easier to
fiddle with |hjust| values than to manipulate |x| values. There are many
other examples where non-standard (other than 0, 0.5 and 1) factors are
used.

These use cases would be very handy if available in ggplot for python
which hinges on this PR.


Reply to this email directly or view it on GitHub
#1181 (comment).

@tacaswell
Copy link
Member

The underlying problem of how to correctly deal with this is vector outputs still remains and, @mdehoon can correct me, I suspect that implementing this in OSX would be non-trivial.

I think you can achieve the effect you want using annotate in almost all cases.

In the SO link, they are just cycling between ['left', 'center', 'right'] which does not require this PR to do.

In the weather plot it looks like the hjust values are hand-coded/tuned and could be achieved via annotate (and in fact given that it looks like the point of that hjust is push the words off of the scatter plot, you could do much better because you know the size of the scatter plot in square pixels (as it comes from your data) and using a combination of ha and xytext with the pixel offset units put the text so that it does not overlap with the scatter plot markers and sits the same place relative to the marker for all of them).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants