query about pyplot.text example

The online documentation at URL=
http://www.scipy.org/Cookbook/Matplotlib/Maps has an example that uses
plt.text as follows:

plt.text(xpt+50000,ypt+50000,name)

Why is the offset 50000?

···

--
View this message in context: http://old.nabble.com/query-about-pyplot.text-example-tp26999119p26999119.html
Sent from the matplotlib - users mailing list archive at Nabble.com.

Dr. Phillip M. Feldman wrote:

The online documentation at URL=
http://www.scipy.org/Cookbook/Matplotlib/Maps has an example that uses
plt.text as follows:

plt.text(xpt+50000,ypt+50000,name)

Why is the offset 50000?

The proj library used by Basemap transforms lon, lat to meters, so xpt and ypt are in meters. Hence the offsets are 50 km. Now, what I don't understand is why the San Diego offset on the map looks so much larger than the Boulder offset, for example.

Eric

Ah. It sounds as though one must consider the scale of the map, and then choose these offsets so that the text falls near but not too near the marker. It would be great if one could specify the text offsets in units of the font size rather than in units of map distance.

Thanks!

Phillip

Eric Firing wrote:

···

Dr. Phillip M. Feldman wrote:

The online documentation at URL=
http://www.scipy.org/Cookbook/Matplotlib/Maps has an example that uses
plt.text as follows:

plt.text(xpt+50000,ypt+50000,name)

Why is the offset 50000?

The proj library used by Basemap transforms lon, lat to meters, so xpt and ypt are in meters. Hence the offsets are 50 km. Now, what I don't understand is why the San Diego offset on the map looks so much larger than the Boulder offset, for example.

Eric

You can do it, it just takes a bit of knowledge about how different
transformations are used under the hood:

import matplotlib.transforms as mtransforms
import matplotlib.pyplot as plt

# Basic plot of single point. Adjust limits to give space
x0,y0 = 4,5
plt.plot(x0, y0, 'o')
plt.ylim(-10, 20)
plt.xlim(0, 15)

# Grab axes object so we can get the tranformation used to
# transform data points into axes coords
ax = plt.gca()

# Create a transform that moves to the data point and then
# adds an offset of 10 up (I'm not sure if it's points or pixels)
# Transforms can be combined using just the simple '+'
trans = ax.transData + mtransforms.Affine2D().translate(0, 10)
plt.text(x0, y0, 'Testing', horizontalalignment='center',
    verticalalignment='center', transform=trans, clip_on=True)

# Now do one 15 right
trans2 = ax.transData + mtransforms.Affine2D().translate(15, 0)
plt.text(x0, y0, 'Testing2', horizontalalignment='left',
    verticalalignment='center', transform=trans2, clip_on=True)

plt.show()

I hope this helps. Let me know if anything is unclear.

Ryan

···

On Sun, Jan 3, 2010 at 1:02 AM, Phillip M. Feldman <pfeldman@...2440...> wrote:

Ah. It sounds as though one must consider the scale of the map, and
then choose these offsets so that the text falls near but not too near
the marker. It would be great if one could specify the text offsets in
units of the font size rather than in units of map distance.

--
Ryan May
Graduate Research Assistant
School of Meteorology
University of Oklahoma

See also, the transforms tutorial:

  http://matplotlib.sourceforge.net/users/transforms_tutorial.html

Offset transformations are discussed at:

  http://matplotlib.sourceforge.net/users/transforms_tutorial.html#using-offset-transforms-to-create-a-shadow-effect

though in a different context, that of creating shadow effects. The
transformation logic is the same as in this case, though.

JDH

···

On Sun, Jan 3, 2010 at 10:22 AM, Ryan May <rmay31@...287...> wrote:

the marker. It would be great if one could specify the text offsets in
units of the font size rather than in units of map distance.

You can do it, it just takes a bit of knowledge about how different
transformations are used under the hood:

John Hunter wrote:

the marker. It would be great if one could specify the text offsets in
units of the font size rather than in units of map distance.

You can do it, it just takes a bit of knowledge about how different
transformations are used under the hood:

See also, the transforms tutorial:

  http://matplotlib.sourceforge.net/users/transforms_tutorial.html

Offset transformations are discussed at:

  http://matplotlib.sourceforge.net/users/transforms_tutorial.html#using-offset-transforms-to-create-a-shadow-effect

though in a different context, that of creating shadow effects. The
transformation logic is the same as in this case, though.

The case of wanting to offset text by an amount measured ideally in units of font size, or, failing that, in display units, is so common that it cries out for an easy-to-use syntax. e.g.,

text(x, y, "Honolulu", offset = (1, 1), offset_units='ex')

I think that allowing display units would be easy to implement (as indicated by Ryan's example), but font or physical units would be much trickier because they would involve draw-time determinations. Starting by allowing only display units still would be much better than the present situation.

Collections already have something like this, with their offset and offset_transform kwargs, but they are still a little more difficult to use than what I am thinking of for text.

Eric

···

On Sun, Jan 3, 2010 at 10:22 AM, Ryan May <rmay31@...287...> wrote:

This would be a nice feature, but a little tricky to do generally
since the text objects are already so complicated ... I mean feature
rich.

One could simply do a draw time offset and convert points->pixels (eg
as in Annotation) but to get everything to play consistently with
annotations, arrows, fancy boxes, etc, would require some care and
thought.

JDH

···

On Sun, Jan 3, 2010 at 2:50 PM, Eric Firing <efiring@...202...> wrote:

I think that allowing display units would be easy to implement (as indicated
by Ryan's example), but font or physical units would be much trickier
because they would involve draw-time determinations. Starting by allowing
only display units still would be much better than the present situation.

Collections already have something like this, with their offset and
offset_transform kwargs, but they are still a little more difficult to use
than what I am thinking of for text.

What is meant by "draw time"?

For most purposes, I think that I'd want to specify an offset in font units (points). If offsets are specified in units of pixels, then the results would be display-dependent, and achieving display-independent results would require some additional fiddling. I would recommend allowing the user to select units of points, pixels, mm, inches, or plot units, with a default of points.

Phillip

John Hunter wrote:

···

On Sun, Jan 3, 2010 at 2:50 PM, Eric Firing <efiring@...202...> wrote:
  

I think that allowing display units would be easy to implement (as indicated
by Ryan's example), but font or physical units would be much trickier
because they would involve draw-time determinations. Starting by allowing
only display units still would be much better than the present situation.

Collections already have something like this, with their offset and
offset_transform kwargs, but they are still a little more difficult to use
than what I am thinking of for text.
    
This would be a nice feature, but a little tricky to do generally
since the text objects are already so complicated ... I mean feature
rich.

One could simply do a draw time offset and convert points->pixels (eg
as in Annotation) but to get everything to play consistently with
annotations, arrows, fancy boxes, etc, would require some care and
thought.

JDH

Phillip M. Feldman wrote:

What is meant by "draw time"?

When you call text(...), a Text object is created and added to a list of things (Artists) to be drawn, but no drawing occurs (unless using pyplot in interactive mode) until a draw(), show(), or savefig() command is given. That's "draw time".

For most purposes, I think that I'd want to specify an offset in font units (points). If offsets are specified in units of pixels, then the results would be display-dependent, and achieving display-independent results would require some additional fiddling. I would recommend allowing the user to select units of points, pixels, mm, inches, or plot units, with a default of points.

Much easier said than done, unfortunately. Not impossible. Who's going to bell the cat?

Eric

···

Phillip

John Hunter wrote:

On Sun, Jan 3, 2010 at 2:50 PM, Eric Firing <efiring@...202...> wrote:

I think that allowing display units would be easy to implement (as indicated
by Ryan's example), but font or physical units would be much trickier
because they would involve draw-time determinations. Starting by allowing
only display units still would be much better than the present situation.

Collections already have something like this, with their offset and
offset_transform kwargs, but they are still a little more difficult to use
than what I am thinking of for text.
    
This would be a nice feature, but a little tricky to do generally
since the text objects are already so complicated ... I mean feature
rich.

One could simply do a draw time offset and convert points->pixels (eg
as in Annotation) but to get everything to play consistently with
annotations, arrows, fancy boxes, etc, would require some care and
thought.

JDH

How about just extending the functionality of the "annotate"? I
believe it should be quite straight forward since "annotate" already
support "offset points". And "points" in matplotlib is dpi
independent.

However, I think calling "annotate" for an offset text is a bit
inconvenient for now.

annotate("Test", (0.5, 0.5), xytext=(10, 10), textcoords="offset points")

And, I prefer Eric's suggestion.

text(x, y, "Honolulu", offset = (1, 1), offset_units='ex')

So, I think one of the easiest way is to
  1) extend annotate to take offsets in some arbitrary units (we may
just add "offset fontsize", "offset ex" as an option for textcoords,
or we may add a new keyword)
  2) then modify "text" to call annotate when there is an "offset" keyword.

Philip, for now, you may use annotate, which I think is a bit easier
to use than working with transformation, and also it gives you a
dpi-independent offset.

Regards,

-JJ