diff --git a/lib/matplotlib/path.py b/lib/matplotlib/path.py index b2540be1c18f..c71cbc828881 100644 --- a/lib/matplotlib/path.py +++ b/lib/matplotlib/path.py @@ -172,7 +172,7 @@ def _fast_from_codes_and_verts(cls, verts, codes, internals=None): Parameters ---------- verts : numpy array - codes : numpy array (may not be None) + codes : numpy array internals : dict or None The attributes that the resulting path should have. Allowed keys are ``readonly``, ``should_simplify``, @@ -182,6 +182,10 @@ def _fast_from_codes_and_verts(cls, verts, codes, internals=None): """ internals = internals or {} pth = cls.__new__(cls) + if ma.isMaskedArray(verts): + verts = verts.astype(np.float_).filled(np.nan) + else: + verts = np.asarray(verts, np.float_) pth._vertices = verts pth._codes = codes pth._readonly = internals.pop('readonly', False) diff --git a/lib/matplotlib/scale.py b/lib/matplotlib/scale.py index cc64d1d66e5e..d541aa86d484 100644 --- a/lib/matplotlib/scale.py +++ b/lib/matplotlib/scale.py @@ -87,12 +87,12 @@ def get_transform(self): def _mask_non_positives(a): """ Return a Numpy masked array where all non-positive values are - masked. If there are no non-positive values, the original array - is returned. + replaced with NaNs. If there are no non-positive values, the + original array is returned. """ mask = a <= 0.0 if mask.any(): - return ma.MaskedArray(a, mask=mask) + return np.where(mask, np.nan, a) return a diff --git a/lib/matplotlib/tests/baseline_images/test_path/semi_log_with_zero.png b/lib/matplotlib/tests/baseline_images/test_path/semi_log_with_zero.png new file mode 100644 index 000000000000..8edfb8a0a64b Binary files /dev/null and b/lib/matplotlib/tests/baseline_images/test_path/semi_log_with_zero.png differ diff --git a/lib/matplotlib/tests/test_path.py b/lib/matplotlib/tests/test_path.py index 3d0c56bd5d43..3304ed653ead 100644 --- a/lib/matplotlib/tests/test_path.py +++ b/lib/matplotlib/tests/test_path.py @@ -72,6 +72,16 @@ def test_point_in_path_nan(): assert not contains[0] +@image_comparison(baseline_images=['semi_log_with_zero'], extensions=['png']) +def test_log_transform_with_zero(): + x = np.arange(-10, 10) + y = (1.0 - 1.0/(x**2+1))**20 + + fig, ax = plt.subplots() + ax.semilogy(x, y, "-o", lw=15) + ax.grid(True) + + if __name__ == '__main__': import nose nose.runmodule(argv=['-s', '--with-doctest'], exit=False) diff --git a/src/_backend_agg.h b/src/_backend_agg.h index 0093443f7e12..8d454a1faaa6 100644 --- a/src/_backend_agg.h +++ b/src/_backend_agg.h @@ -502,7 +502,8 @@ inline void RendererAgg::draw_markers(GCAgg &gc, agg::rgba color) { typedef agg::conv_transform transformed_path_t; - typedef PathSnapper snap_t; + typedef PathNanRemover nan_removed_t; + typedef PathSnapper snap_t; typedef agg::conv_curve curve_t; typedef agg::conv_stroke stroke_t; typedef agg::pixfmt_amask_adaptor pixfmt_amask_type; @@ -515,14 +516,16 @@ inline void RendererAgg::draw_markers(GCAgg &gc, trans *= agg::trans_affine_translation(0.5, (double)height + 0.5); transformed_path_t marker_path_transformed(marker_path, marker_trans); - snap_t marker_path_snapped(marker_path_transformed, + nan_removed_t marker_path_nan_removed(marker_path_transformed, true, marker_path.has_curves()); + snap_t marker_path_snapped(marker_path_nan_removed, gc.snap_mode, marker_path.total_vertices(), points_to_pixels(gc.linewidth)); curve_t marker_path_curve(marker_path_snapped); transformed_path_t path_transformed(path, trans); - snap_t path_snapped(path_transformed, SNAP_FALSE, path.total_vertices(), 0.0); + nan_removed_t path_nan_removed(path_transformed, false, false); + snap_t path_snapped(path_nan_removed, SNAP_FALSE, path.total_vertices(), 0.0); curve_t path_curve(path_snapped); path_curve.rewind(0);