开发者

How can I plot points so they appear over top of the spines with matplotlib?

开发者 https://www.devze.com 2023-01-15 19:15 出处:网络
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 quart

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:

How can I plot points so they appear over top of the spines with matplotlib?

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))

How can I plot points so they appear over top of the spines with matplotlib?


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.

0

精彩评论

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