Skip to content

Inconsistent edges of half-filled markers #14357

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
pyZerrenner opened this issue May 28, 2019 · 2 comments
Open

Inconsistent edges of half-filled markers #14357

pyZerrenner opened this issue May 28, 2019 · 2 comments
Labels
keep Items to be ignored by the “Stale” Github Action topic: markers

Comments

@pyZerrenner
Copy link

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
@anntzer
Copy link
Contributor

anntzer commented Jan 24, 2021

I would guess the "proper" solution is to add a clipmask to the half-filled markers, defined by the extend of the non-halffilled markers. (This would handle the spikes at the top of the example; the holes at the bottom can be more simply handled by passing closed=True to the path definitions.)
Likely that'll require a bit of surgery to achieve...

Here's a full list:

from pylab import *
from matplotlib.markers import MarkerStyle


ax = plt.figure(figsize=(12, 8)).add_subplot()
ax.set_axis_off()
for i, m in enumerate(MarkerStyle.filled_markers):
    for j, fs in enumerate(MarkerStyle.fillstyles):
        ax.plot(i, j, marker=m, fillstyle=fs, ms=25, mew=3,
                mec="b", mfc="r", mfcalt="g")
for i, m in enumerate(MarkerStyle.filled_markers):
    ax.text(i, j + 1, m, ha="center")
plt.show()

test
(which also shows that the half-filled "h" style is missing a midline, unlike all other markers).

I think I found a solution to the problem, although it may be running into an Agg bug :( See the new definition of set_diamond in #19354; now we just need to do the same for all other markers, and perhaps figure out the Agg bug... (https://svgwg.org/svg2-draft/painting.html#TermLineJoinShape may be relevant too.)

@github-actions
Copy link

This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!

@github-actions github-actions bot added the status: inactive Marked by the “Stale” Github Action label Jun 19, 2023
@anntzer anntzer added keep Items to be ignored by the “Stale” Github Action and removed status: inactive Marked by the “Stale” Github Action labels Jun 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
keep Items to be ignored by the “Stale” Github Action topic: markers
Projects
None yet
Development

No branches or pull requests

3 participants