Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
510 views
in Technique[技术] by (71.8m points)

python - Matplotlib Line Overlap/Resolution

I'm making a plot in Matplotlib where it is imperative for different lines to not overlap when they have differing x-values. For some reason, when I draw lines, there is overlap if they are close enough together (but not overlapping). For example,

fig = plt.figure(num=None, facecolor='w', edgecolor='k')
ax = fig.add_subplot(2, 1, 1)
ax.plot((0, 10000000), (3, 3), linewidth = 2, markersize = 0, clip_on = True, aa = True)
ax.plot((10000001, 200000001), (3, 3), linewidth = 1, markersize = 0, clip_on = True, aa = True)

plt.savefig('test.png', format='png')

enter image description here I want the blue line and the green line to not overlap at all, since 10000000 < 10000001.

I made the blue line slightly thicker, so if you zoom in, you can see how the blue and green lines overlap. I made the dpi very high, so it isn't a resolution problem. I will have to be dealing with large numbers because I am working with genome data--are the large numbers an issue? When I plot with x-values of (0 to 10000) and (10001, 20000), the problem still exists.

Thanks so much for your help.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

It has to do with the cap style of the Line2D object, the default style is 'projecting', which result in overlapping, see a zoom-in-ed PDF: enter image description here

We want to change it to 'butt' style:

L1=ax.plot((0, 10000000), (3, 3), linewidth = 2, markersize = 0, clip_on = True, aa = True)
L2=ax.plot((10000001, 200000001), (3, 3), linewidth = 1, markersize = 0, clip_on = True, aa = True)
for item in L1+L2:
    item.set_solid_capstyle('butt')

enter image description here

The gap is very small, sure, since it is 1/10000000.

Or if you want, a quick dirty solution is just to draw a small white circle marker of size=1 at (10000000.5, 3).


fig, ax = plt.subplots(1, 1, figsize=(8, 4))

L1 = ax.plot((0, 1), (1, 1), linewidth=10, label='No capstyle')
L2 = ax.plot((1, 2), (1, 1), linewidth=7, label='No capstyle')


L3 = ax.plot((0, 1), (0.9, 0.9), linewidth=10, solid_capstyle='butt', label='With butt capstyle')
L4 = ax.plot((1, 2), (0.9, 0.9), linewidth=7, solid_capstyle='butt', label='With butt capstyle')

ax.set_ylim(0, 2)
ax.grid()
ax.legend()

enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...