Why is the plotted line blurry?

340 Views Asked by At

I have code that creates the following plot:

enter image description here

Zooming in on the line, we can see that instead of being just black, it has a black core and is gray/slightly transparent on the sides (see figure below). Is it possible to make the line fully black?

enter image description here

Here is the code that is used for the plotting:

import matplotlib.pyplot as plt
import numpy as np


plt.plot([10,10],[10,20],color='k',linewidth=1)
plt.show()

Increasing the dpi does not work, and I want the linewidth to remain the same.

1

There are 1 best solutions below

1
JohanC On

The effect you see is called antialiasing and important in computer graphics to make lines drawn at any angle look similar when drawn with the same thickness.

Almost always, the measure for distances isn't an integer value when calculated in pixels. Without antialiasing x and y positions need to be rounded to the nearest pixel.

plt.plot() (and similar functions) has an optional argument antialiased= which you can set to False to see how things look like. Depending on your specific application, this might work for you.

Here is an example. It uses lw=0.2 to show the effect more strongly. With thicker lines, the same effect will still be there, but less visible. Note that matplotlib measures lines in "points" (1/72 of an inch, similar to the "points" used to indicate font size). Due to different rounding and positions not falling onto integer pixels, some lines are thicker, and diagonal lines look very jagged.

from matplotlib import pyplot as plt

plt.plot([i // 10 * 10 for i in range(0, 100, 5)], [0, 10] * 10, antialiased=False, color='black', lw=0.2)

turning off antialiasing

Zoomed in view:

zoomed in on image without antialiasing

PS: Here is an example with plt.contour():

import numpy as np
from matplotlib import pyplot as plt

xs, ys = np.meshgrid(np.linspace(0, 1, 30), np.linspace(0, 1, 20))
zs = np.random.randn(*xs.shape).cumsum(axis=0).cumsum(axis=1)

plt.contour(xs, ys, zs, cmap='Spectral', antialiased=False)
plt.show()

This is how it looks like overall and zoomed-in:

non-antialiased contour plot

I tested this with maptlotlib 3.5.3 on Windows, with the 'TkAgg' backed.

An alternative would be to save your plot to a vector format (e.g. .svg) and do the further processing via an editor such as InkScape.