[Matplotlib-users] contourf looking ugly with transparent colors

Remo Goetschi surf at libecciu.ch
Wed Nov 11 08:28:26 EST 2015


Hi,

Does somebody know how to produce a good-looking filled contour plot
with semi-transparent colors? If contourf() is passed a colormap with
semi-transparent colors, it produces small gaps between the filled areas:
http://i.stack.imgur.com/eEQXI.png

According to the docs, this is not a bug ("contourf() [...] does not
draw the polygon edges"). To draw the edges, it is suggested to "add
line contours with calls to contour()". But that doesn't look good
either as the edges become too opaque:
http://i.stack.imgur.com/s17F9.png
You can play with the linewidth argument of contour(), but that doesn't
help much. Any ideas?

The code that reproduces the problem is attached below (I use the
object-oriented API, but the result is the same with pyplot).

BTW, pcolormesh() suffers from a similar problem:
http://i.stack.imgur.com/Gbwcb.png

Both problems do not seem to occur with the SVG backend.

I asked the same question already on stackoverflow. Feel free to respond
there:
http://stackoverflow.com/questions/33547926/matplotlib-filled-contour-plot-with-transparent-colors

Thanks,
Remo

---------
import matplotlib
import numpy as np
from matplotlib.figure import Figure
from matplotlib.backends.backend_agg import FigureCanvasAgg

# generate some data
shape = (100, 100)
x_rng = np.linspace(-1, 1, shape[1])
y_rng = np.linspace(-1, 1, shape[0])
x, y = np.meshgrid(x_rng, y_rng)
z = np.sqrt(x**2 + y**2)

# create figure
width_inch, height_inch = 5, 5  # results in 500x500px with dpi=100
fig = Figure()
fig.set_size_inches((width_inch, height_inch))
FigureCanvasAgg(fig)
ax = fig.add_axes([0., 0., 1., 1.])
ax.set_axis_off()

# define some colors with alpha < 1
alpha = 0.9
colors = [
    (0.1, 0.1, 0.5, alpha),  # dark blue
    (0.0, 0.7, 0.3, alpha),  # green
    (0.9, 0.2, 0.7, alpha),  # pink
    (0.0, 0.0, 0.0, alpha),  # black
    (0.1, 0.7, 0.7, alpha),  # light blue
]
cmap = matplotlib.colors.ListedColormap(colors)
levels = np.array(np.linspace(0, z.max(), len(colors)))
norm = matplotlib.colors.BoundaryNorm(levels, ncolors=cmap.N)

# contourf plot produces small gaps between filled areas
cnt = ax.contourf(x, y, z, levels, cmap=cmap, norm=norm,
                  antialiased=True, linecolor='none')

# this fills the gaps, but it makes them too opaque
# ax.contour(x, y, z, levels, cmap=cmap, norm=norm,
#            antialiased=True)

# the same is true for this trick:
# for c in cnt.collections:
#     c.set_edgecolor("face")

filename = "/tmp/contourf.png"
fig.savefig(filename, dpi=100, transparent=True, format="png")
print("Saved plot to {}.".format(filename))


More information about the Matplotlib-users mailing list