[Matplotlib-users] contourf looking ugly with transparent colors

Jens Nielsen jenshnielsen at gmail.com
Wed Nov 11 09:53:09 EST 2015


The issue you are seeing is slightly different from the one the docs
mention.
I wrote the docs suggesting the work around and this is mainly relevant for
vector backends (PDF and so on) The problem with PDF viewers is that many
of them create visible gaps when two polygons are rendered next to each
other with zero overlap. This is a viewer specific thing but lots of
viewers suffers from this.
This effect is much more visible that the one you see. I think the one you
see is due to the way the edge between the 2 colours is antialiased by the
render.

The work around with adding  edges is only a workaround exactly as you
remarked because it doesn't work well with non transparent surfaces.

best
Jens

On Wed, 11 Nov 2015 at 13:44 Remo Goetschi <surf at libecciu.ch> wrote:

> 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))
> _______________________________________________
> Matplotlib-users mailing list
> Matplotlib-users at python.org
> https://mail.python.org/mailman/listinfo/matplotlib-users
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/matplotlib-users/attachments/20151111/5b9d61e3/attachment.html>


More information about the Matplotlib-users mailing list