Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Boxplot fix median line extending past box boundaries #19409#26462

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged

Conversation

@kidkoder432
Copy link
Contributor

@kidkoder432kidkoder432 commentedAug 7, 2023
edited
Loading

PR summary

Fixes#19409
The median line on a boxplot would extend past the box when the line width was increased. This PR aims to fix the visual annoyance by setting the solid line capstyle to be the same as all other capstyles. additionally, this change keeps the capstyle of the median lines consistent with other boxplot lines (i.e. mean lines).

This is my second ever PR so be nice please :)

Other changes:

PR checklist

Other changes:- Update `.gitignore` to ignore `venv/` in commit- Fixed a small typo in `bxp()`- Added a new test for the median line (from PRmatplotlib#23335)
Copy link

@github-actionsgithub-actionsbot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Thank you for opening your first PR into Matplotlib!

If you have not heard from us in a week or so, please leave a new comment below and that should bring it to our attention. Most of our reviewers are volunteers and sometimes things fall through the cracks.

You can also join uson gitter for real-time discussion.

For details on testing, writing docs, and our review process, please seethe developer guide

We strive to be a welcoming and open project. Please follow ourCode of Conduct.

@melissawm
Copy link
Member

Hi@kidkoder432 - while we wait for a proper review, would you mind taking a look at the Linting failure here?https://github.com/matplotlib/matplotlib/actions/runs/5780696475/job/15664707497?pr=26462

It looks like you are missing a blank line in your test.

Copy link
Member

@rcomerrcomer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Thank you for your work on this@kidkoder432, but I do not think this is currently the right change.

@rcomerrcomer added status: needs revision PR: bugfixPull requests that fix identified bugs labelsAug 8, 2023
@kidkoder432
Copy link
ContributorAuthor

kidkoder432 commentedAug 8, 2023 via email

Oh okay, thanks! (This is my first contribution to matplotlib so Iappreciate the feedback :))
On Tue, Aug 8, 2023 at 12:01 AM Ruth Comer ***@***.***> wrote: ***@***.**** commented on this pull request. Thank you for your work on this@kidkoder432 <https://github.com/kidkoder432>, but I do not think this is currently the right change. ------------------------------ In lib/matplotlib/axes/_axes.py <#26462 (comment)> : > @@ -4095,7 +4095,7 @@ def bxp(self, bxpstats, positions=None, widths=None, vert=True, capwidths : float or array-like, default: None Either a scalar or a vector and sets the width of each cap. - The default is ``0.5*(with of the box)``, see *widths*. + The default is ``0.5*(width of the box)``, see *widths*. Nice spot! ------------------------------ In lib/matplotlib/lines.py <#26462 (comment)> : > @@ -297,7 +297,7 @@ def __init__(self, xdata, ydata, *, markerfacecoloralt='none', fillstyle=None, antialiased=None, - dash_capstyle=None, + dash_capstyle="butt", I think you intended to change *solid_capstyle* rather than *dash_capstyle*, but I do not think we want to do this here. This will define the default capstyle for lines used all over the library, and will override what the user has set in their rcParams (see the logic below with if solid_capstyle is None:, etc.) For the current issue, I think we only want to change the capstyle used by default within boxplot for the median line. As noted in#19409 <#19409>, you can get at that in the medianprops dictionary. — Reply to this email directly, view it on GitHub <#26462 (review)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AOYIALWGZ6KQXTFQWGJIMH3XUHP5BANCNFSM6AAAAAA3GLM3QA> . You are receiving this because you were mentioned.Message ID: ***@***.***>
rcomer reacted with thumbs up emoji

@rcomer
Copy link
Member

This change has caused some test failures.@kidkoder432 are you confident to investigate those yourself? You can see the full output from the tests by clicking the "Details" link by one of the checks at the bottom of this page. You can also run the tests yourself locally:
https://matplotlib.org/devdocs/devel/testing.html

@kidkoder432
Copy link
ContributorAuthor

This change has caused some test failures.@kidkoder432 are you confident to investigate those yourself? You can see the full output from the tests by clicking the "Details" link by one of the checks at the bottom of this page. You can also run the tests yourself locally:https://matplotlib.org/devdocs/devel/testing.html

Sure, I'll take a look and let you know any concerns.

@kidkoder432
Copy link
ContributorAuthor

kidkoder432 commentedAug 12, 2023
edited
Loading

Edit: I fixed theNoneType errors that were occurring when amedianprops dictionary was not provided, but those same tests now fail withImageComparisonFailure:

Okay, so I looked at the failing tests and noticed that the expected images were all using a capstyle ofprojecting. However, because I modified the code to use a capstyle ofbutt. the original tests for median lines were failing because they were expecting aprojecting capstyle. However, this capstyle is the reason why the median line was extending past the box. According to thedocs:

'projecting'
the line is squared off as inbutt, but the filled-in area extends beyond the endpoint a distance oflinewidth/2.

I'm not sure how to move forward with this.

Sometimes the `medianprops` dict was not provided so the previous code was failing to assign a key to it. So a check was added to either modify an exsisting dict or create a new one.
@rcomer
Copy link
Member

rcomer commentedAug 12, 2023
edited
Loading

OK, if the user specifies a capstyle then we should assume they are happy with their choice and leave it. We should only set it to “butt” if the user didn’t make a choice. I think the dictionarysetdefault method might be useful here.

@kidkoder432
Copy link
ContributorAuthor

OK, if the user specifies a capstyle then we should assume they are happy with their choice and leave it. We should only set it to “butt” if the user didn’t make a choice. I think the dictionarysetdefault method might be useful here.

Good idea.
Those tests don't seem to define a capstyle specifically though, so they still fail...

@rcomer
Copy link
Member

Ah OK, I thought you meant that some tests were specifying “projecting” as the capstyle. Instead they are just leaving it to default and this change switches the default from “projecting” to “butt”. So the tests are failing because of a genuine (desired) change in the output, which means you will need to replace the reference images. We have thetriage_tests tool to help with that.

I used the triage tests tool to set the test benchmark images to those with a capstyle of `butt`. I also modieifed the behaviror for setting the capstyle for median lines to obey the user's preference instead of overriding it.
@rcomer
Copy link
Member

Thanks for the update@kidkoder432. It looks like you still have a couple of image test failures for pdf files. Do you see those failures locally? If not you might be missing a dependency - most likely ghostscript.
https://matplotlib.org/devdocs/devel/dependencies.html#dependencies-for-testing-matplotlib

@kidkoder432
Copy link
ContributorAuthor

kidkoder432 commentedAug 16, 2023 via email

i don't see them locally; i probably do need to install ghostscript.How would I resolve the PDF test failures?
On Wed, Aug 16, 2023, 12:00 PM Ruth Comer ***@***.***> wrote: Thanks for the update@kidkoder432 <https://github.com/kidkoder432>. It looks like you still have a couple of image test failures for pdf files. Do you see those failures locally? If not you might be missing a dependency - most likely ghostscript.https://matplotlib.org/devdocs/devel/dependencies.html#dependencies-for-testing-matplotlib — Reply to this email directly, view it on GitHub <#26462 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AOYIALX7ALTX6FGE4YKIQ33XVUKGTANCNFSM6AAAAAA3GLM3QA> . You are receiving this because you were mentioned.Message ID: ***@***.***>

@rcomer
Copy link
Member

I think thetriage_tests script should handle pdf as well as png.

@kidkoder432
Copy link
ContributorAuthor

kidkoder432 commentedAug 16, 2023 via email

Got it, thank you!
On Wed, Aug 16, 2023, 12:10 PM Ruth Comer ***@***.***> wrote: I think the triage_tests script should handle pdf as well as png. — Reply to this email directly, view it on GitHub <#26462 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AOYIALQJRPPJJSWYAPEUTYLXVULKTANCNFSM6AAAAAA3GLM3QA> . You are receiving this because you were mentioned.Message ID: ***@***.***>
rcomer reacted with thumbs up emoji

@kidkoder432
Copy link
ContributorAuthor

I'm having trouble getting pytest to recognize that I have Ghostscript installed. are there any resources for this on the matplotlib docs?

i used the installer to install Ghostscript 10.01.2.

@ksunden
Copy link
Member

Matplotlib only interacts with ghostscript via subprocess calls. Can you callgs as a CLI program (e.g.gs --help) (on windows it may also be calledgswin64c, not really sure what is fully going on there...)

If it is not in your PATH, it will not be found, so make sure it is installed in a place that it can be executed.

@kidkoder432
Copy link
ContributorAuthor

kidkoder432 commentedAug 19, 2023 via email

I use VSCode for development. If I run gswin64 from a regular powershellterminal, it launches a command window to type gs commands with (gs is insystem PATH). However, this command does not work in VSCode, and pdf testsare skipped by pytest.How do I resolve this so i can continue development? Thanks.
On Fri, Aug 18, 2023 at 12:17 AM Kyle Sunden ***@***.***> wrote: Matplotlib only interacts with ghostscript via subprocess calls. Can you call gs as a CLI program (e.g. gs --help) (on windows it may also be called gswin64c, not really sure what is fully going on there...) If it is not in your PATH, it will not be found, so make sure it is installed in a place that it can be executed. — Reply to this email directly, view it on GitHub <#26462 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AOYIALUH646NVJQ3JGQTYZLXV4JHRANCNFSM6AAAAAA3GLM3QA> . You are receiving this because you were mentioned.Message ID: ***@***.***>

@kidkoder432
Copy link
ContributorAuthor

kidkoder432 commentedAug 19, 2023 via email

Never mind, i got it to work.
On Fri, Aug 18, 2023, 6:22 PM prajwal agrawal ***@***.***> wrote: I use VSCode for development. If I run gswin64 from a regular powershell terminal, it launches a command window to type gs commands with (gs is in system PATH). However, this command does not work in VSCode, and pdf tests are skipped by pytest. How do I resolve this so i can continue development? Thanks. On Fri, Aug 18, 2023 at 12:17 AM Kyle Sunden ***@***.***> wrote:> Matplotlib only interacts with ghostscript via subprocess calls. Can you> call gs as a CLI program (e.g. gs --help) (on windows it may also be> called gswin64c, not really sure what is fully going on there...)>> If it is not in your PATH, it will not be found, so make sure it is> installed in a place that it can be executed.>> —> Reply to this email directly, view it on GitHub> <#26462 (comment)>,> or unsubscribe> <https://github.com/notifications/unsubscribe-auth/AOYIALUH646NVJQ3JGQTYZLXV4JHRANCNFSM6AAAAAA3GLM3QA>> .> You are receiving this because you were mentioned.Message ID:> ***@***.***>>
rcomer reacted with hooray emoji

The boxplot PDFs were using the wrong capstyle, so I modified the references to use the butt captyle.
@kidkoder432
Copy link
ContributorAuthor

Hi, for some reason it says that CodeCov tests failed in the workflow logs. However, when I visit the website, its says that codecov tests all passed. Can someone please take a look at this?

@rcomer
Copy link
Member

I wouldn’t worry about that codecov failure. We currently use codecovfor information only. In this case, codecov says that 100% of your change is covered, which I think is the important thing. The coverage reductions are all “indirect changes” - I haven’t really got my head around how those are caused myself.

kidkoder432and others added2 commitsAugust 19, 2023 08:38
Co-authored-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>
@kidkoder432
Copy link
ContributorAuthor

kidkoder432 commentedAug 19, 2023 via email

Yes, it makes sense. Thank you for the explanation!
On Sat, Aug 19, 2023 at 10:40 AM Ruth Comer ***@***.***> wrote: ***@***.**** commented on this pull request. ------------------------------ In lib/matplotlib/axes/_axes.py <#26462 (comment)> : > + if medianprops is None: # Clamp median line to edge of box + medianprops = {"solid_capstyle": "butt"} + else: + medianprops.setdefault("solid_capstyle", "butt") Good question. Suppose a user has a dictionary of properties that they re-use for multiple different plot types in their script. If that dictionary gets added to when they pass it to boxplot, then it could affect other plots that are created further down the script. That would be unexpected (and therefore undesirable) behaviour. Does that make sense? You are right that setdefault won’t change the dictionary if it already has that key. — Reply to this email directly, view it on GitHub <#26462 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AOYIALRSMA26DNRGEXL4GNDXWD3CHANCNFSM6AAAAAA3GLM3QA> . You are receiving this because you were mentioned.Message ID: ***@***.***>
rcomer reacted with thumbs up emoji

Copy link
Member

@rcomerrcomer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

This looks good to me now. For code changes, we require approvals from two reviewers so this can’t be merged just yet. Thank you for your work on it@kidkoder432!

kidkoder432 reacted with laugh emojikidkoder432 reacted with rocket emoji
Copy link
Member

@timhoffmtimhoffm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Question: Does anybody understand why the box borders are sometimes shifted slightly?

Comment: The original issue also discussed bringing the line below the box using zorder. This is not discussed in this PR, While conceptually desireable, this is not so easy to fix: The box can be filled and then face and edge are drawn with the same zorder. This means, one cannot draw mean/median lines below the box edge but above the box face (at least not without complicating the draw logic).
I'm therefore inclinded to accept the PR without addressing zorder, but would like to have at least one second thought on this.

"""
# Clamp median line to edge of box by default.
medianprops= {
"solid_capstyle":"butt",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I think we should unversally "solid_capstyle" and "dashed_capstyle" to "butt" for bothmedianprops andmeanprops. We want the lines to end within the box for both independent of the global capstyle settings.

Copy link
ContributorAuthor

@kidkoder432kidkoder432Aug 20, 2023
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

done

@kidkoder432
Copy link
ContributorAuthor

Question: Does anybody understand why the box borders are sometimes shifted slightly?

Comment: The original issue also discussed bringing the line below the box using zorder. This is not discussed in this PR, While conceptually desireable, this is not so easy to fix: The box can be filled and then face and edge are drawn with the same zorder. This means, one cannot draw mean/median lines below the box edge but above the box face (at least not without complicating the draw logic).
I'm therefore inclinded to accept the PR without addressing zorder, but would like to have at least one second thought on this.

Not sure why either... From what you explained about the draw logic it would likely be much easier to stay with the current implementation.

@rcomer
Copy link
Member

Question: Does anybody understand why the box borders are sometimes shifted slightly?

Do you have an example? When I looked at the test images that have changed here, all the diffs seemed to just show the median line getting shorter.

I'm therefore inclinded to accept the PR without addressing zorder, but would like to have at least one second thought on this.

I came to same conclusion based on@oscargus' comment on the previous PR:#23335 (comment)

@timhoffm
Copy link
Member

Do you have an example? When I looked at the test images that have changed here, all the diffs seemed to just show the median line getting shorter.

Can't find anymore. Either I was wrong or this was somehow fixed through the recent updates.

@timhoffmtimhoffm added this to thev3.8.0 milestoneAug 21, 2023
@timhoffm
Copy link
Member

Since this is a bugfix, I recon that it can still go into 3.8.0 (on the basis that we do not have release candidates for any bugfix releases, there's no difference between deferring to 3.8.1 and pushing this into 3.8.0 even after 3.8.0rc1).

@timhoffm
Copy link
Member

Thanks@kidkoder432, and congratulations on your first contrbution to matplotlib! We'd happy to see you back!

rcomer reacted with hooray emoji

ksunden added a commit that referenced this pull requestAug 21, 2023
…462-on-v3.8.xBackport PR#26462 on branch v3.8.x (Boxplot fix median line extending past box boundaries#19409)
@kidkoder432
Copy link
ContributorAuthor

kidkoder432 commentedAug 22, 2023 via email

You're welcome! Thank you for your support!I'll definitely be back to contribute :)
On Mon, Aug 21, 2023, 1:28 PM Tim Hoffmann ***@***.***> wrote: Thanks@kidkoder432 <https://github.com/kidkoder432>, and congratulations on your first contrbution to matplotlib! We'd happy to see you back! — Reply to this email directly, view it on GitHub <#26462 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AOYIALXG77XIXJIN4LCEWILXWPAHDANCNFSM6AAAAAA3GLM3QA> . You are receiving this because you were mentioned.Message ID: ***@***.***>
timhoffm reacted with thumbs up emojircomer reacted with heart emoji

@ksundenksunden mentioned this pull requestSep 15, 2023
5 tasks
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@QuLogicQuLogicQuLogic left review comments

@github-actionsgithub-actions[bot]github-actions[bot] left review comments

@timhoffmtimhoffmtimhoffm approved these changes

@rcomerrcomerrcomer approved these changes

Assignees

No one assigned

Labels

PR: bugfixPull requests that fix identified bugs

Projects

Milestone

v3.8.0

Development

Successfully merging this pull request may close these issues.

Boxplot: Median line too long after changing linewidth

6 participants

@kidkoder432@melissawm@rcomer@ksunden@timhoffm@QuLogic

[8]ページ先頭

©2009-2025 Movatter.jp