diff --git a/doc/users/whats_new.rst b/doc/users/whats_new.rst
index b45bacdf9a9a..b87bc11ce098 100644
--- a/doc/users/whats_new.rst
+++ b/doc/users/whats_new.rst
@@ -148,6 +148,13 @@ default quality is 95; previously, the default quality was 75. This change
minimizes the artifacting inherent in JPEG images, particularly with images
that have sharp changes in color as plots often do.
+Full control of the background color
+------------------------------------
+Wes Campaigne and Phil Elson fixed the Agg backend such that PNGs are now
+saved with the correct background color when :meth:`fig.patch.get_alpha` is
+not 1.
+
+
.. _whats-new-1-2-2:
new in matplotlib 1.2.2
diff --git a/lib/matplotlib/backends/backend_agg.py b/lib/matplotlib/backends/backend_agg.py
index d7a81b7e8f07..865a8fd0013f 100644
--- a/lib/matplotlib/backends/backend_agg.py
+++ b/lib/matplotlib/backends/backend_agg.py
@@ -16,9 +16,8 @@
TODO:
- * allow save to file handle
-
* integrate screen dpi w/ ppi and text
+
"""
from __future__ import division
import threading
@@ -438,7 +437,7 @@ def draw(self):
"""
if __debug__: verbose.report('FigureCanvasAgg.draw', 'debug-annoying')
- self.renderer = self.get_renderer()
+ self.renderer = self.get_renderer(cleared=True)
# acquire a lock on the shared font cache
RendererAgg.lock.acquire()
@@ -449,7 +448,7 @@ def draw(self):
- def get_renderer(self):
+ def get_renderer(self, cleared=False):
l, b, w, h = self.figure.bbox.bounds
key = w, h, self.figure.dpi
try: self._lastKey, self.renderer
@@ -459,6 +458,8 @@ def get_renderer(self):
if need_new_renderer:
self.renderer = RendererAgg(w, h, self.figure.dpi)
self._lastKey = key
+ elif cleared:
+ self.renderer.clear()
return self.renderer
def tostring_rgb(self):
diff --git a/lib/matplotlib/backends/backend_pdf.py b/lib/matplotlib/backends/backend_pdf.py
index 6b688cee8b10..bc1e09e34ab3 100644
--- a/lib/matplotlib/backends/backend_pdf.py
+++ b/lib/matplotlib/backends/backend_pdf.py
@@ -436,7 +436,7 @@ def __init__(self, filename):
revision = ''
self.infoDict = {
- 'Creator': 'matplotlib %s, http://matplotlib.sf.net' % __version__,
+ 'Creator': 'matplotlib %s, http://matplotlib.org' % __version__,
'Producer': 'matplotlib pdf backend%s' % revision,
'CreationDate': datetime.today()
}
diff --git a/lib/matplotlib/tests/baseline_images/test_figure/alpha_background.png b/lib/matplotlib/tests/baseline_images/test_figure/alpha_background.png
new file mode 100644
index 000000000000..cc3ccda25dac
Binary files /dev/null and b/lib/matplotlib/tests/baseline_images/test_figure/alpha_background.png differ
diff --git a/lib/matplotlib/tests/baseline_images/test_figure/alpha_background.svg b/lib/matplotlib/tests/baseline_images/test_figure/alpha_background.svg
new file mode 100644
index 000000000000..f59b35d81258
--- /dev/null
+++ b/lib/matplotlib/tests/baseline_images/test_figure/alpha_background.svg
@@ -0,0 +1,47 @@
+
+
+
+
diff --git a/lib/matplotlib/tests/test_agg.py b/lib/matplotlib/tests/test_agg.py
index 7caf5c5fc622..1be2e7fb5292 100644
--- a/lib/matplotlib/tests/test_agg.py
+++ b/lib/matplotlib/tests/test_agg.py
@@ -1,6 +1,50 @@
from __future__ import print_function
import os
+import tempfile
+
+
+from numpy.testing import assert_array_almost_equal
+
+
+from matplotlib.image import imread
+from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
+from matplotlib.figure import Figure
+from matplotlib.testing.decorators import cleanup
+
+
+@cleanup
+def test_repeated_save_with_alpha():
+ # We want an image which has a background color of bluish green, with an
+ # alpha of 0.25.
+
+ fig = Figure([1, 0.4])
+ canvas = FigureCanvas(fig)
+ fig.set_facecolor((0, 1, 0.4))
+ fig.patch.set_alpha(0.25)
+
+ # The target color is fig.patch.get_facecolor()
+
+ _, img_fname = tempfile.mkstemp(suffix='.png')
+ try:
+ fig.savefig(img_fname,
+ facecolor=fig.get_facecolor(),
+ edgecolor='none')
+
+ # Save the figure again to check that the
+ # colors don't bleed from the previous renderer.
+ fig.savefig(img_fname,
+ facecolor=fig.get_facecolor(),
+ edgecolor='none')
+
+ # Check the first pixel has the desired color & alpha
+ # (approx: 0, 1.0, 0.4, 0.25)
+ assert_array_almost_equal(tuple(imread(img_fname)[0, 0]),
+ (0.0, 1.0, 0.4, 0.250),
+ decimal=3)
+ finally:
+ os.remove(img_fname)
+
def report_memory(i):
pid = os.getpid()
@@ -64,3 +108,8 @@ def report_memory(i):
## # w/o text and w/o write_png: Average memory consumed per loop: 0.02
## # w/o text and w/ write_png : Average memory consumed per loop: 0.3400
## # w/ text and w/ write_png : Average memory consumed per loop: 0.32
+
+
+if __name__ == "__main__":
+ import nose
+ nose.runmodule(argv=['-s', '--with-doctest'], exit=False)
diff --git a/lib/matplotlib/tests/test_figure.py b/lib/matplotlib/tests/test_figure.py
index f6f033feef0b..6aefb95ca62f 100644
--- a/lib/matplotlib/tests/test_figure.py
+++ b/lib/matplotlib/tests/test_figure.py
@@ -74,6 +74,25 @@ def test_suptitle():
fig.suptitle('title', color='g', rotation='30')
+@image_comparison(baseline_images=['alpha_background'],
+ # only test png and svg. The PDF output appears correct,
+ # but Ghostscript does not preserve the background color.
+ extensions=['png', 'svg'],
+ savefig_kwarg={'facecolor': (0, 1, 0.4), 'edgecolor': 'none'})
+def test_alpha():
+ # We want an image which has a background color and an
+ # alpha of 0.4.
+ fig = plt.figure(figsize=[2, 1])
+ fig.set_facecolor((0, 1, 0.4))
+ fig.patch.set_alpha(0.4)
+
+ import matplotlib.patches as mpatches
+ fig.patches.append(mpatches.CirclePolygon([20, 20],
+ radius=15,
+ alpha=0.6,
+ facecolor='red'))
+
+
if __name__ == "__main__":
import nose
nose.runmodule(argv=['-s', '--with-doctest'], exit=False)
diff --git a/src/_backend_agg.cpp b/src/_backend_agg.cpp
index fa9f93ae14eb..96ddf920e3a4 100644
--- a/src/_backend_agg.cpp
+++ b/src/_backend_agg.cpp
@@ -411,7 +411,7 @@ RendererAgg::RendererAgg(unsigned int width, unsigned int height, double dpi,
renderingBuffer.attach(pixBuffer, width, height, stride);
pixFmt.attach(renderingBuffer);
rendererBase.attach(pixFmt);
- rendererBase.clear(agg::rgba(1, 1, 1, 0));
+ rendererBase.clear(agg::rgba(0, 0, 0, 0));
rendererAA.attach(rendererBase);
rendererBin.attach(rendererBase);
hatchRenderingBuffer.attach(hatchBuffer, HATCH_SIZE, HATCH_SIZE,
@@ -1108,7 +1108,7 @@ RendererAgg::draw_image(const Py::Tuple& args)
inv_mtx.invert();
typedef agg::span_allocator color_span_alloc_type;
- typedef agg::image_accessor_clip
+ typedef agg::image_accessor_clip
image_accessor_type;
typedef agg::span_interpolator_linear<> interpolator_type;
typedef agg::span_image_filter_rgba_nn renderer_base;
typedef agg::renderer_scanline_aa_solid renderer_aa;
typedef agg::renderer_scanline_bin_solid renderer_bin;
diff --git a/src/_image.cpp b/src/_image.cpp
index 520c8a82aa4b..13377eeed3e7 100644
--- a/src/_image.cpp
+++ b/src/_image.cpp
@@ -33,7 +33,7 @@
#include "mplutils.h"
-typedef agg::pixfmt_rgba32 pixfmt;
+typedef agg::pixfmt_rgba32_plain pixfmt;
typedef agg::pixfmt_rgba32_pre pixfmt_pre;
typedef agg::renderer_base renderer_base;
typedef agg::span_interpolator_linear<> interpolator_type;