开发者

matplotlib annotate xycoords=('data','axes fraction') => TypeError: 'NoneType' object is not iterable

>>> import matplotlib
>>> matplotlib.__version__
'0.99.1.1'

the following code runs:

import matplotlib.pyplot as plt
plt.figure()
ax=plt.axes([.1, .1, .8, .8])
ax.annotate('++++', xy=(.5,.2), xycoords='data')
ax.annotate('aaaa', xy=(.5,.4), xycoords='axes fraction')
#ax.annotate('bbbb', xy=(.5,.6), xycoords=('data', 'axes fraction'))
plt.show()

but the commented-out ax.annotate gives an error:

TypeError: 'NoneType' object is not iterable

it is supposedly correct code according to the current docs:

From: http://matplotlib.sourceforge.net/users/annotations_guide.html

4. A tuple of two coordinate specification. 
   The first item is for x-coordi开发者_JAVA技巧nate and 
   the second is for y-coordinate. 
   For example,

        annotate("Test", xy=(0.5, 1), xycoords=("data", "axes fraction"))

    0.5 is in data coordinate, and 1 is in normalized axes coordinate.

any ideas on what is going on?

EDIT: since first posting, i have been looking at a workaround, and discovered another issue. When xycoords='data', the annotataion is still clipped if it falls outside the axes, even with clip_on=False. Here is the code that demonstrates this:

import matplotlib.pyplot as plt
plt.figure()
ax=plt.axes([.1, .1, .8, .8])
ax.annotate('cccc', xy=(.3, .5), xycoords='data', clip_on=False)
ax.annotate('dddd', xy=(.3,-.1), xycoords='data', clip_on=False)
ax.annotate('eeee', xy=(.6,-.1), xycoords='axes fraction', clip_on=False)
plt.show()


Using a tuple to indicate different x and y transforms for annotate was added in matplotlib 1.0. Here's the relevant commit, if anyone's interested. You'll need to upgrade to the latest version to use it.

For the second problem, this is actually the documented behavior. (clip_on is a generic matplotlib text artist kwarg. Annotation artists don't behave in the same way, apparently.)

From: http://matplotlib.sourceforge.net/api/pyplot_api.html#matplotlib.pyplot.annotate

The annotation_clip attribute contols the visibility of the annotation when it goes outside the axes area. If True, the annotation will only be drawn when the xy is inside the axes. If False, the annotation will always be drawn regardless of its position. The default is None, which behave as True only if xycoords is”data”.

You'll need to use the annotation_clip kwarg, instead:

import matplotlib.pyplot as plt
plt.figure()
ax=plt.axes([.1, .1, .8, .8])
ax.annotate('cccc', xy=(.3, .5), xycoords='data', annotation_clip=False)
ax.annotate('dddd', xy=(.3,-.1), xycoords='data', annotation_clip=False)
ax.annotate('eeee', xy=(.6,-.1), xycoords='axes fraction', annotation_clip=False)
plt.show()

See this thread on the matplotlib-users list for more discussion (and also note that the annotation_clip kwarg might be broken on 0.99.1, so you may need to use the workaround there.)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜