Skip to content

Inconsistent edges of half-filled markers #14357

Open
@pyZerrenner

Description

@pyZerrenner

Bug report

Bug summary

The edges of some half-filled markers either produce spikes or are missing parts.

Code for reproduction

import matplotlib.pyplot as plt

fig, ax = plt.subplots(figsize=(2.2, 1.4))
ax.set_xlim(-0.5, 5)
ax.set_axis_off()

sty = dict(marker='D', fillstyle='right', markerfacecoloralt='r',
           markerfacecolor='g', markeredgecolor='#00000088')
plt.plot([0], [0], **sty)
plt.plot([1], [0], markeredgewidth=10, **sty)
plt.plot([3], [0], markeredgewidth=10, markersize=30, **sty)

This code produces the following image
marker_D_miter

Expected output
The outer marker edges should build a rectangle like for fully filled markers. The spikes and missing parts of the edge are not as noticeable for the default marker size (left), but they can still be visible when printed from a vector image (e.g. pdf). (The transparency of the edges is just to more clearly show the two paths the marker edge is composed of.)
When looking into the matplotlib.markers.MarkerStyle._set_diamond method, there are three issues generating this output:

  1. The marker paths are not closed. This causes the asymmetry of the edge at the top and bottom of the marker.
  2. The join-style of the edge is set to 'miter', which causes the spikes at the top since the corner has a very sharp 45° angle.
  3. The cap-style of the edge defaults to 'butt'. At the marker bottom the edge path starts and ends and does not complete the corner.

The same issue appears for the other half-filled styles 'left', 'top' and 'bottom' (since they only rotate the marker differently). Other markers have similar issues (e.g. 's', '^', 'd', 'h').
My current solution is to set the join-style and cap-style to 'rounded' at the end of the MarkerStyle._set_diamond method

self._joinstyle = 'round'
self._capstyle = 'round'

This produces the output
marker_D_round
The corners are now round instead of pointy, but the spikes and missing parts are gone and the marker is symmetric.

A more general solution would be better, though. This would maybe require using custom paths for the edges instead of reusing the paths of the marker faces. But I'm not sure whether this can be easily implemented.

Matplotlib version

  • Operating system: Windows 10
  • Matplotlib version: 3.0.3
  • Matplotlib backend: Qt5Agg & inline
  • Python version: 3.7 & 3.6

Metadata

Metadata

Assignees

No one assigned

    Labels

    keepItems to be ignored by the “Stale” Github Actiontopic: markers

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions