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

fix xkcd context#9521

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

Closed
jklymak wants to merge1 commit intomatplotlib:masterfromjklymak:fixxkcd
Closed

Conversation

jklymak
Copy link
Member

PR Summary

Fixes xkcd context so that one can do (as per#9520):

importmatplotlib.pyplotaspltwithplt.xkcd():plt.figure()plt.plot([1,2,3])plt.savefig('xkcd.png',dpi=300)plt.figure()plt.plot([1,2,3])plt.savefig('not_xkcd.png',dpi=300)

PR Checklist

  • Code is PEP 8 compliant

@tacaswell
Copy link
Member

I do not understand how either the change to the context manager nor this change fixes it.

@jklymak
Copy link
MemberAuthor

Before it was just setting the rcParams to the new xkcd values and not passing them to the context. I don't understand how it worked before ;-)

@tacaswell
Copy link
Member

Ah, I understand. Before the clean up ofrc_context the previous state was cached on__init__, now it is stashed on__enter__.

This PR fixes the case of a context manager, but I suspect breaks if you just call

plt.xkcd()fig,ax=plt.subplots()...

@jklymak
Copy link
MemberAuthor

Um yeah I guess so.

I find this a strange function in that it passes parameters to a style.

@jklymak
Copy link
MemberAuthor

I’d actually propose an xkcd style and deprecating this function. If folks want to monkey with the randomness of the lines they can call the style and then do so directly with the rcparams.

I’m too dense to know how to make this work as both a context and directly changing the rcParams.

@anntzer
Copy link
Contributor

So you just need to add a call tocontext.__enter__() right after creating the context (in the old version of the code).
contextlib.ExitStack would make this easier to write :-)

@jklymak
Copy link
MemberAuthor

Ok that’s easy.

@anntzer
Copy link
Contributor

xkcd style will not work because the rcparams machinery is messed up (or pick a less strong qualifier)#6157

@jklymak
Copy link
MemberAuthor

frommatplotlibimportpatheffectscontext=rc_context()context.__enter__()

yields

Traceback (most recent call last):  File "testxkcd.py", line 3, in <module>    with plt.xkcd():  File "/Users/jklymak/anaconda3/envs/matplotlibdev/lib/python3.6/contextlib.py", line 83, in __enter__    raise RuntimeError("generator didn't yield") from NoneRuntimeError: generator didn't yield

@anntzer
Copy link
Contributor

Bah, we were doing something way too complex.

-    context = rc_context()-    try:-        rcParams['font.family'] = ['xkcd', 'Humor Sans', 'Comic Sans MS']-        rcParams['font.size'] = 14.0-        rcParams['path.sketch'] = (scale, length, randomness)-        rcParams['path.effects'] = [-            patheffects.withStroke(linewidth=4, foreground="w")]-        rcParams['axes.linewidth'] = 1.5-        rcParams['lines.linewidth'] = 2.0-        rcParams['figure.facecolor'] = 'white'-        rcParams['grid.linewidth'] = 0.0-        rcParams['axes.grid'] = False-        rcParams['axes.unicode_minus'] = False-        rcParams['axes.edgecolor'] = 'black'-        rcParams['xtick.major.size'] = 8-        rcParams['xtick.major.width'] = 3-        rcParams['ytick.major.size'] = 8-        rcParams['ytick.major.width'] = 3-    except:-        context.__exit__(*sys.exc_info())-        raise-    return context+    return rc_context({+        'font.family': ['xkcd', 'Humor Sans', 'Comic Sans MS'],+        'font.size': 14.0,+        'path.sketch': (scale, length, randomness),+        'path.effects': [patheffects.withStroke(linewidth=4, foreground="w")],+        'axes.linewidth': 1.5,+        'lines.linewidth': 2.0,+        'figure.facecolor': 'white',+        'grid.linewidth': 0.0,+        'axes.grid': False,+        'axes.unicode_minus': False,+        'axes.edgecolor': 'black',+        'xtick.major.size': 8,+        'xtick.major.width': 3,+        'ytick.major.size': 8,+        'ytick.major.width': 3,+    })

works (I tried it!).

@jklymak
Copy link
MemberAuthor

I thought thats what I did ?

@anntzer
Copy link
Contributor

... sorry, not paying attention. back to the drawing board.

@jklymak
Copy link
MemberAuthor

Yeah, that doesn't work for@tacaswell case...

@jklymak
Copy link
MemberAuthor

Sorry to be dense about the context management. I can close this PR and let you work on it if easier.

FWIW,@tacaswell case isn't actually documented or tested anywhere! Its implied in the docstring.

@anntzer
Copy link
Contributor

anntzer commentedOct 22, 2017
edited
Loading

this actually works in both cases

    from contextlib import ExitStack    stack = ExitStack    stack.enter_context(rc_context({        'font.family': ['xkcd', 'Humor Sans', 'Comic Sans MS'], ...    })    return stack

(except that it needs a backport of contextlib.ExitStack (or similar) on AncientPython, e.g.https://pypi.python.org/pypi/contextlib2/0.5.5).

Basically we want to enter the rc_context but returnanother context that does nothing on enter but pops the rc_context on exit. ExitStack exactly provides that functionality.

As pointed out by@tacaswell#8962 indeed broke backcompat for whoever was usingrc_context(...)without entering the context as a synonym forrc(...). I can't say I have much sympathy for this use case.

@jklymak
Copy link
MemberAuthor

xkcd style will not work because the rcparams machinery is messed up (or pick a less strong qualifier)

Is this becausepath.effects wants a function, and there is no way to enter a function in a style sheet?

Is it possible to have a style-sheet parser fcn that reads a string frompath.effects and makes sure it is calling something frompatheffects before setting it?

@jklymak
Copy link
MemberAuthor

OK, I suggest this change is consistent w/ the most documentation for now.

I suggest a way forward is to parse style sheets for strings that have patheffect calls, but to explicitly callpatheffect.XX ourselves to prevent security risks. There may be a fancier way to do that. But then folks could juststyles.use('xkcd') like any other style. See#6157

@jklymak
Copy link
MemberAuthor

Closing in lieu of#9603

@tacaswell
Copy link
Member

Thanks for your work on this@jklymak !

@jklymak
Copy link
MemberAuthor

No problem -@anntzer solution is very cool!

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers
No reviews
Assignees
No one assigned
Labels
None yet
Projects
None yet
Milestone
v2.1.1
Development

Successfully merging this pull request may close these issues.

3 participants
@jklymak@tacaswell@anntzer

[8]ページ先頭

©2009-2025 Movatter.jp