[Matplotlib-users] contourf looking ugly with transparent colors

Eric Firing efiring at hawaii.edu
Fri Nov 13 13:08:30 EST 2015


On 2015/11/11 3:28 AM, Remo Goetschi 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

There are potentially two problems, depending on whether anti-aliasing 
is on.

Without anti-aliasing, the fundamental problem is how pixels are filled 
in adjacent patches with a common boundary specified as floating point. 
This should be solvable, but it might be down in the darkest corners of agg.

With anti-aliasing, I think the problem is inherent and has no solution, 
thought there might be ways its visual effect could be reduced in common 
cases.  The problem here is that antialiasing fuzzes the boundary by 
fading out pixels depending on how much of the pixel is outside a patch. 
  With alpha not equal to one, this means that the background, and 
anything plotted earlier, shows through. Therefore the end result 
depends on the background color, and will in general not be just a blend 
of the two colors of the adjacent patches, which is what one intended. 
It can be darker or lighter, etc.

I think that in other filled contour implementations (Matlab, Ferret) 
the problems we see in mpl with some renderers even with no transparency 
and no antialiasing are absent because they build a stack of 
superimposed filled regions instead of adjacent regions.  We could 
provide an option to do this.

Eric

>
> 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
>



More information about the Matplotlib-users mailing list