Skip to content

[Bug]: offset dash linestyle has no effect in patch objects #22977

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

Closed
oliverpriebe opened this issue May 4, 2022 · 7 comments · Fixed by #23412
Closed

[Bug]: offset dash linestyle has no effect in patch objects #22977

oliverpriebe opened this issue May 4, 2022 · 7 comments · Fixed by #23412
Labels
Difficulty: Easy https://matplotlib.org/devdocs/devel/contribute.html#good-first-issues Good first issue Open a pull request against these issues if there are no active ones! status: has patch patch suggested, PR still needed
Milestone

Comments

@oliverpriebe
Copy link

Bug summary

When setting the linestyle on a patch object using a dash tuple the offset has no effect.

Code for reproduction

import matplotlib.pyplot as plt
import matplotlib as mpl

plt.figure(figsize=(10,10))
ax = plt.gca()
ax.add_patch(mpl.patches.Rectangle((0.5,0.5),1,1, alpha=0.5, edgecolor = 'r', linewidth=4, ls=(0,(10,10))))
ax.add_patch(mpl.patches.Rectangle((0.5,0.5),1,1, alpha=0.5, edgecolor = 'b', linewidth=4, ls=(10,(10,10))))
plt.ylim([0,2])
plt.xlim([0,2])
plt.show()

Actual outcome

Screen Shot 2022-05-04 at 4 45 33 PM

the patch edge lines overlap, not adhering to the offset.

Expected outcome

Haven't been able to get any patch objects to have a proper offset on the edge line style but the expected outcome is shown here with Line2D objects

import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np

ax_g = plt.gca()

x = np.linspace(0, np.pi*4, 100)
y = np.sin(x+np.pi/2)
z = np.sin(x+np.pi/4)
w = np.sin(x)

plt.plot(x, y, ls=(0, (10, 10)), color='b')
plt.plot(x, y, ls=(10, (10, 10)), color='r')
plt.show()

Screen Shot 2022-05-04 at 4 59 25 PM

Additional information

I have tried the Ellipse patch object as well and found the same issue. I also reproduced in Ubuntu 18.04 VM running matplotlib 3.5.0 with agg backend.

Operating system

OS/X

Matplotlib Version

3.3.4

Matplotlib Backend

MacOSX

Python version

Python 3.8.8

Jupyter version

No response

Installation

conda

@oliverpriebe
Copy link
Author

Upon digging deeper into this issue it appears that this actually the intended behavior:

# Patch has traditionally ignored the dashoffset.

So it might be prudent to just update the docstring to reflect this fact.

I'm curious why this was made the default behavior though

@oliverpriebe
Copy link
Author

replacing the 0 here with the passed offset works completely fine on my OSX and Ubuntu setups.

self, _dash_pattern=(0, self._dash_pattern[1])), \

@tacaswell
Copy link
Member

@oliverpriebe Why do you want to do this?

On one hand, we will sort out how to manage changing behavior when we need to, but on the other hand we need to have a very good reason to change long-standing behavior!

@oliverpriebe
Copy link
Author

I'd like to use edge colors (red/blue) to denote a binary property of an entity represented by a rectangular patch that may overlap exactly with another entity with the opposite property value. When they overlap I'd like to easily see the two colors -- which isn't possible by just using low alphas.

Admittedly this is both a niche use case and can be worked around by hacking the onoffseq as so

plt.figure(1); plt.clf()
ax = plt.gca()
ax.add_patch(mpl.patches.Rectangle(
                  (0, 0),
                  1, 1,
                  facecolor = 'gray',
                  edgecolor = 'r',
                  linestyle = (0, [6, 0, 0, 6]),
                  fill = True
                ))
ax.add_patch(mpl.patches.Rectangle(
                  (0, 0),
                  1, 1,
                  facecolor = 'gray',
                  edgecolor = 'r',
                  linestyle = (0, [0, 6, 6, 0]),
                  fill = True
                ))
ax.set_xlim([-2, 2])
ax.set_ylim([-2, 2])

@oliverpriebe
Copy link
Author

but it might save the next poor soul some time if the docstring was updated

@timhoffm
Copy link
Member

timhoffm commented May 5, 2022

I couldn't find a reason why we should ignore dash offset here. If this was intended, we should issue a warning if the user sets a non-zero value. However I rather think this was an oversight and even though noticed, nobody bothered to take action.

# Patch has traditionally ignored the dashoffset.

This is a niche feature that almost nobody will use. But AFAICS, there's little harm in supporting offests here. The only user code we could break with that is if users would explicitly have set an offset but rely on it not being applied. That's not something we'd have to guard against. To me this is simply a bug (affecting very little users), and we could fix it right away.

@oscargus oscargus added Difficulty: Easy https://matplotlib.org/devdocs/devel/contribute.html#good-first-issues Good first issue Open a pull request against these issues if there are no active ones! status: has patch patch suggested, PR still needed labels Jun 4, 2022
@oscargus
Copy link
Member

oscargus commented Jun 4, 2022

Marking this as good first issue as there is a minor modification required. Most work will be related to tests, probably an equality test with the workaround and the fixed code, and writing a sensible user release note clarifying that this has been fixed.

@QuLogic QuLogic added this to the v3.6.0 milestone Aug 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Difficulty: Easy https://matplotlib.org/devdocs/devel/contribute.html#good-first-issues Good first issue Open a pull request against these issues if there are no active ones! status: has patch patch suggested, PR still needed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants