Re: [Matplotlib-users] Drawing a circle around a letter

2010-12-28 Thread Paul Ivanov
Nathann Cohen, on 2010-12-26 22:27,  wrote:
 Hello everybody !!!
 
 When adding some text to a plot, is there a way to know the actual
 size of the letters as they appear, in such a way that I could, for
 instance, draw a circle around a 'A', so that the A perfectly fits
 inside (the smallest circle containing the letter), regardless of
 the actual size of the picture I'm drawing ?

Hi Nathann,

Here's a quick and dirty way of getting what you want:

  import matplotlib.pyplot as plt
  import numpy as np
  ax = plt.subplot(111)
  t = plt.text(0.5,0.5,'A', ha='center', va='center')
  plt.draw()
  b = t.get_window_extent() # bounding box in pixel coordinates
  r = np.sqrt((b.bounds[-2]/2)**2 + (b.bounds[-1]/2)**2)
  plt.scatter(0.5,0.5, s=np.pi*r**2, marker='o', edgecolor='k', facecolor='w', 
lw=1,zorder=-1)

I don't think there's a super simple way of doing this by hand -
because text keeps its size constant regardless of how you
manipulate the axes. Here's an example that does what you want,
if you only need the circle in one particular view (i.e. if you
won't be rescaling/zooming in or out the axes:

  ax = plt.subplot(111)
  plt.plot([0,1,1],[0,0,1]) # keep the axes from resizing when we draw our 
circle
  t = plt.text(0.5,0.5,'A')
  plt.axis('equal')
  plt.draw()
  b = t.get_window_extent() # bounding box in pixel coordinates
  bbox = b.inverse_transformed(ax.transData)
  xc,yc = bbox.get_points().mean(0)
  r = np.sqrt((bbox.bounds[-2]/2)**2 + (bbox.bounds[-1]/2)**2)
  theta = np.linspace(0,2*np.pi,200)
  x,y = r*(np.cos(theta)), r*np.sin(theta)
  l = plt.plot(x+xc, y+yc)

This does exactly what you want, but now, anytime you resize the
axes, the A will stay the same size, but that circle will get
resized.

  ax = plt.subplot(111)
  plt.plot([0,1,1],[0,0,1]) # keep the axes from resizing when we draw our 
circle
  t = plt.text(0.5,0.5,'A')
  plt.axis('equal')
  plt.draw()
  b = t.get_window_extent() # bounding box in pixel coordinates
  bbox = b.inverse_transformed(ax.transAxes)
  xc,yc = bbox.get_points().mean(0)
  r = np.sqrt((bbox.bounds[-2]/2)**2 + (bbox.bounds[-1]/2)**2)
  theta = np.linspace(0,2*np.pi,200)
  x,y = r*(np.cos(theta)), r*np.sin(theta)
  l = plt.plot(x+xc, y+yc, transform=ax.transAxes)

The above will keep the circle from resizing when you move - but
now it prevents the circle from following 'A' as you pan around.

I see that matplotlib.collections (which is what plt.scatter
creates in the quick-and-dirty example) uses offset and
transOffset to get the job done, but I couldn't figure out a way
to get my last two examples to do something similar by just
manipulating the transforms. 

Hopefully someone chimes in with a better solution. For more on
transformations see:
http://matplotlib.sourceforge.net/users/transforms_tutorial.html

And you can wrap my hand-rolled solution nicely using something
like:
http://matplotlib.sourceforge.net/examples/api/line_with_text.html

best, 
-- 
Paul Ivanov
314 address only used for lists,  off-list direct email at:
http://pirsquared.org | GPG/PGP key id: 0x0F3E28F7 


signature.asc
Description: Digital signature
--
Learn how Oracle Real Application Clusters (RAC) One Node allows customers
to consolidate database storage, standardize their database environment, and, 
should the need arise, upgrade to a full multi-node Oracle RAC database 
without downtime or disruption
http://p.sf.net/sfu/oracle-sfdevnl___
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users


Re: [Matplotlib-users] Drawing a circle around a letter

2010-12-28 Thread Jae-Joon Lee
With bbox parameter, you can draw a box (or a path) around a text.

http://matplotlib.sourceforge.net/users/annotations_guide.html#annotating-with-text-with-box

There a several box styles, but unfortunately no circle. However, you
can create a custom box style.

http://matplotlib.sourceforge.net/users/annotations_guide.html#define-custom-boxstyle

Attached is an modified example in the above link that draws a circle.

IHTH,

-JJ




On Mon, Dec 27, 2010 at 6:27 AM, Nathann Cohen nathann.co...@gmail.com wrote:
 Hello everybody !!!

 When adding some text to a plot, is there a way to know the actual
 size of the letters as they appear, in such a way that I could, for
 instance, draw a circle around a 'A', so that the A perfectly fits
 inside (the smallest circle containing the letter), regardless of
 the actual size of the picture I'm drawing ?

 Pray excuse me if my question has an obvious answer... I am working on
 Sage's library (http://www.sagemath.org/) which uses Matplotlib...
 This code is not very clear to me, not to mention it is my first
 contact with Matplotlib... Thank you for your extreme patience :-)

 Nathann

 --
 Learn how Oracle Real Application Clusters (RAC) One Node allows customers
 to consolidate database storage, standardize their database environment, and,
 should the need arise, upgrade to a full multi-node Oracle RAC database
 without downtime or disruption
 http://p.sf.net/sfu/oracle-sfdevnl
 ___
 Matplotlib-users mailing list
 Matplotlib-users@lists.sourceforge.net
 https://lists.sourceforge.net/lists/listinfo/matplotlib-users



boxstyle_circle.py
Description: Binary data
--
Learn how Oracle Real Application Clusters (RAC) One Node allows customers
to consolidate database storage, standardize their database environment, and, 
should the need arise, upgrade to a full multi-node Oracle RAC database 
without downtime or disruption
http://p.sf.net/sfu/oracle-sfdevnl___
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users