user6765044
user6765044

Reputation: 61

How to get matplotlib to place lines accurately?

By default, matplotlib plot can place lines very inaccurately.

For example, see the placement of the left endpoint in the attached plot. There's at least a whole pixel of air that shouldn't be there. In fact I think the line center is 2 pixels off.

How to get matplotlib to draw accurately? I don't mind if there is some performance hit.

Inaccurately rendered line in matplotlib plot:

inaccurately rendered line in matplotlib plot

Inaccurately rendered line in matplotlib plot - detail magnified:

inaccurately rendered line in matplotlib plot - detail magnified

This was made with the default installations in Ubuntu 16.04 (Python 3), Jupyter notebook (similar result from command line).

Mathematica, for comparison, does subpixel-perfect rendering directly and by default: Same thing rendered by Mathematica Why can't we?

Upvotes: 6

Views: 1336

Answers (3)

Kristjan Jonasson
Kristjan Jonasson

Reputation: 523

I completely agree that this should be worked on. I find that plt.plot gives (at least more or less) unshifted lines (in Jupyter) by calling plt.figure with dpi=144 (the default is 72). The figures do become twice as big though...

Upvotes: 0

andres
andres

Reputation: 1109

The problem is even more notorious when one plots functions which are symmetric with respect to the x axis and slowly approach zero. As for example here: enter image description here

which is indeed embarrassing if you are telling the reader of a scientific paper that the two curves are symmetric!

I went around this problem by exporting to pdf instead of exporting to png:

enter image description here

Upvotes: 3

tacaswell
tacaswell

Reputation: 87366

Consider the following to see what is going on

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.plot([1, 2, 3], [4, 5, 4], clip_on=False, lw=5, alpha=.5)
ax.set_xlim([1, 3])

fig.savefig('so.png', dpi=400)

example

You can also disable pixel snapping by passing snap=False to plot, however once you get down to placing ~ single pixel wide line, you are going to have issues because the underlying rasterization is too coarse.

Upvotes: 3

Related Questions