The following generates a plot with three data points, at (0, 0), (0, 0.5), and (1, 1). Only that portion of the plotted points (small circles) which lie inside the plot area is visible, so I see quarter-circles in the corners, and a half circle along the left spine.
Is there a trick I can use to make all the points fully visible, so they are not clipped within the axes frame?
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure
fig = Figure()
canvas = FigureCanvas(fig)
ax = fig.add_subplot(111)
ax.plot([0, 0, 1], [0, 0.5, 1], 'o')
fig.canvas.print_figure('test.png')
Edit: Amro's suggestion -- the obvious approach -- is not the preferred approach as these are for ROC graphs (conventionally drawn with a box from 0 to 1 on both axes). If I could trick matplotlib into producing results similar to the many at http://www.google.com/search?q=roc+plot which have a box tightly around 0..1 on both axes, yet have points drawn on top of the axis lines as many of them do开发者_JAVA百科, that would be optimal.
Edit 2: I'm guessing this can be done using "spine placement" (new as of MPL 0.99), with the plot area enlarged slightly as Amro suggested, but then with the spines repositioned slightly to be along both 0 axes. I'll experiment with this and post an answer if it works, though feel free to beat me to it.
You can turn the clipping off, either in the plot command, or in the artist objects returned by a call to "plot".
First, here's the figure, with extra big symbols so it's clear:
In the plot command you can do
ax.plot([0, 0, 1], [0, 0.5, 1], 'o', clip_on=False, markersize=20)
or you could have
p = ax.plot([0, 0, 1], [0, 0.5, 1], 'o', markersize=20)
for m in p:
m.set_clip_on(False)
You can extend the axes limits a bit in all directions:
ax = fig.add_subplot(111, xlim=(-0.1,1.1), ylim=(-0.1,1.1))
I combined my idea using the new spine.set_position() capability with Amro's suggestion to expand the bounds slightly. The following works with only with matplotlib 1.0 or later, as it relies on the new spine.set_bounds() call. (I believe Amro's idea needed 1.0 or later as well, since the xlim/ylim kwargs did nothing for me with 0.99.1.)
fig = Figure()
canvas = FigureCanvas(fig)
ax = fig.add_subplot(111, xlim=(-0.1, 1.1), ylim=(-0.1, 1.1))
ax.plot([0, 0, 1], [0, 0.5, 1], 'o')
for side in 'left bottom top right'.split():
ax.spines[side].set_position('zero')
ax.spines[side].set_bounds(0, 1)
canvas.print_figure('test.png')
I'd still be quite interested to hear if there's a different approach, but my guess after much googling is that matplotlib has a basic restriction around this area: all data is tightly clipped by the region defined for the axis.
精彩评论