diff --git a/lib/matplotlib/markers.py b/lib/matplotlib/markers.py index fea9150d1a71..a6588c7c67f5 100644 --- a/lib/matplotlib/markers.py +++ b/lib/matplotlib/markers.py @@ -277,13 +277,13 @@ def _set_pixel(self): # Ideally, you'd want -0.5, -0.5 here, but then the snapping # algorithm in the Agg backend will round this to a 2x2 # rectangle from (-1, -1) to (1, 1). By offsetting it - # slightly, we can force it to be (0, -1) to (1, 0), which - # both makes it only be a single pixel and places it correctly - # with 1-width stroking (i.e. the ticks). This hack is the - # best of a number of bad alternatives, mainly because the + # slightly, we can force it to be (0, 0) to (1, 1), which both + # makes it only be a single pixel and places it correctly + # aligned to 1-width stroking (i.e. the ticks). This hack is + # the best of a number of bad alternatives, mainly because the # backends are not aware of what marker is actually being used # beyond just its path data. - self._transform = Affine2D().translate(-0.49999, -0.50001) + self._transform = Affine2D().translate(-0.49999, -0.49999) self._snap_threshold = None def _set_point(self): diff --git a/src/_backend_agg.cpp b/src/_backend_agg.cpp index f7a986fc2f95..96a9402ac0a8 100644 --- a/src/_backend_agg.cpp +++ b/src/_backend_agg.cpp @@ -433,10 +433,10 @@ RendererAgg::set_clipbox(const Py::Object& cliprect, R& rasterizer) double l, b, r, t; if (py_convert_bbox(cliprect.ptr(), l, b, r, t)) { - rasterizer.clip_box(std::max(int(mpl_round(l)), 0), - std::max(int(height) - int(mpl_round(b)), 0), - std::min(int(mpl_round(r)), int(width)), - std::min(int(height) - int(mpl_round(t)), int(height))); + rasterizer.clip_box(std::max(int(floor(l - 0.5)), 0), + std::max(int(floor(height - b - 0.5)), 0), + std::min(int(floor(r - 0.5)), int(width)), + std::min(int(floor(height - t - 0.5)), int(height))); } else { @@ -650,7 +650,7 @@ RendererAgg::draw_markers(const Py::Tuple& args) // Deal with the difference in y-axis direction marker_trans *= agg::trans_affine_scaling(1.0, -1.0); trans *= agg::trans_affine_scaling(1.0, -1.0); - trans *= agg::trans_affine_translation(0.0, (double)height); + trans *= agg::trans_affine_translation(0.5, (double)height + 0.5); PathIterator marker_path(marker_path_obj); transformed_path_t marker_path_transformed(marker_path, marker_trans); @@ -736,8 +736,8 @@ RendererAgg::draw_markers(const Py::Tuple& args) continue; } - x = (double)(int)x; - y = (double)(int)y; + x = floor(x); + y = floor(y); // Cull points outside the boundary of the image. // Values that are too large may overflow and create @@ -772,8 +772,8 @@ RendererAgg::draw_markers(const Py::Tuple& args) continue; } - x = (double)(int)x; - y = (double)(int)y; + x = floor(x); + y = floor(y); // Cull points outside the boundary of the image. // Values that are too large may overflow and create diff --git a/src/path_converters.h b/src/path_converters.h index c45ff862c6f6..faacf15ad924 100644 --- a/src/path_converters.h +++ b/src/path_converters.h @@ -494,8 +494,8 @@ class PathSnapper code = m_source->vertex(x, y); if (m_snap && agg::is_vertex(code)) { - *x = mpl_round(*x) + m_snap_value; - *y = mpl_round(*y) + m_snap_value; + *x = floor(*x - m_snap_value) + m_snap_value; + *y = floor(*y - m_snap_value) + m_snap_value; } return code; }