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

 Re: [Matplotlib-users] Drawing a circle around a letter From: Paul Ivanov - 2010-12-28 10:27:41 Attachments: application/pgp-signature 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

### Thread view

 [Matplotlib-users] Drawing a circle around a letter From: Nathann Cohen - 2010-12-26 21:27:23 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
 Re: [Matplotlib-users] Drawing a circle around a letter From: Paul Ivanov - 2010-12-28 10:27:41 Attachments: application/pgp-signature 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
 Re: [Matplotlib-users] Drawing a circle around a letter From: Jae-Joon Lee - 2010-12-29 02:05:06 Attachments: boxstyle_circle.py 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 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@... > https://lists.sourceforge.net/lists/listinfo/matplotlib-users >