-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
[WIP] Property Cycling #4686
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
[WIP] Property Cycling #4686
Conversation
That might be an aggressive deprecation schedule, there are a lot of examples of people relying on color cycle in scary ways. I suspect we are going to have to stub out the get/set methods and provide a read/write property to fake up the old way for a very long time (3.0?). |
Can't we keep both (at least for now)? |
Actually, what is getting removed/changed are methods of a class that starts with an underscore and is generated dynamically, and is accessed through methods that have an underscore. I kept around Axes.set_color_cycle(), though. |
Ahh, sorry, I didn't see the class name, I dislike that github doesn't show that when it snips. |
Just thinking about this a bit. One thing that breaks backwards compatibility is that axes.color_cycle is pretty much completely ignored. While the default prop_cycle is identical to the old approach, what if someone applies a style sheet that does not have this new cycle, or if someone programmatically sets this rc param. Maybe it makes sense to augment the axes.color_cycle semantics rather than adding a new property? So, if someone passes a simple list of colors, then transparently create a cycler object for colors. But if it is a cycler object (or a string that can be eval'ed as a cycler), then we treat it as such? |
I think we can fake complete back compatibility with enough |
Just pushed up some more fixes that should bring down the number of test failures/errors significantly. @tacaswell , I am not sure how you envision using properties to solve the problem I mentioned. The rc params is just a giant dictionary, right? I think we need to have a mechanism for aliasing rcparam values. |
Oh, wow... the standard set of tests pass (it doesn't on my system due to font issues). Ok, I'll put up some tests tonight and see how they do. I am still second-guessing myself with the creation of a new rcparam and deprecation of the current one, as opposed to over-loading the current one. |
added some tests, discovered that bar() doesn't support property cycling (but fill() does). Although, I can't seem to get hatching to cycle for it... |
hatching + color seems to not get along, try setting 'facecolor' and 'edgecolor' different. I ran into this last night in https://github.com/matplotlib/matplotlib/pull/4433/files?diff=unified |
if prop_cycler is None and 'axes.color_cycle' in rcParams: | ||
clist = rcParams['axes.color_cycle'] | ||
prop_cycler = cycler('color', clist) | ||
self.prop_cycler = itertools.cycle(prop_cycler) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should probably tag next version of cycler which includes __call__
-> infinite cycle
re: hatching, confirmed that using facecolor instead of color allowed the hatching to work. I suspect what is happening is that the hatch is getting the same color as 'color'. If I set 'facecolor' to 'none', then the hatches show up. Shouldn't hatches default color come from 'lines.linecolor'? Do we have a way to set the color of a hatch? |
That all sounds like something to fix in 2.0! |
@WeatherGod What is the state of this? |
I need to figure out how to avoid the color/facecolor collision issue. I On Thu, Aug 6, 2015 at 4:09 PM, Thomas A Caswell notifications@github.com
|
So, I had an idea last night about how to fix the issue with setting properties. Consider the situation of a "color" and an "edgecolor" being specified for a Polygon object at the same time:
Right now, that will result in a warning, and the edgecolor will end up being red (Don't know if that should be desired behavior, but that's a separate issue.). This is because the Patch constructor tries to handle potential conflicts with properties. However, if I subsequently do a
Then the result is random because it is iterating over a dictionary. If you set color after setting edgecolor, then both the face and the edge will be yellow, but if the edgecolor gets set after the color, then the edge will be black while the face will be yellow. Personally, I think that the latter result should be the desired behavior, but for consistency with the constructor, I think the former result should be desired. So, what is my solution? A more complete solution would be that each artist subclass should be defining a priority order for their properties. That priority order would then be used by At the very least, this should resolve the randomness issue we are encountering, and it should solve the issue we are having with wrapping up this particular PR. Thoughts? |
👍 on the sort. I think the precedence order issues can be addressed by traitlets @rmorshea ? That said, there is also a question of user intent. If I do ln.set_facecolor('r')
ln.set_color('g') I expect everything about the line to be green. Another option is to have a |
In the example you just gave, the properties are set independently of each On Fri, Aug 14, 2015 at 3:15 PM, Thomas A Caswell notifications@github.com
|
@WeatherGod Sorry, my last comment was not well thought and and missing a big chunk of context that was in my head. That context is having |
@tacaswell If I correctly understand what you're attempting to do with precedential assignments, there isn't any Traitlets magic that will do that for you out of the box. Ordering the actual value assignments would probably have similar solutions in Traitlets as it would elsewhere (I'd probably use a context manager if I were to do it). On the other hand, ordering the "trait change callbacks" is something that could be done with minimal modifications to |
I think I got it! Wait 'till you see this doozy! There are still some odds-n-ends to complete: documentation, testing of new rcparams, rebasing off master to get the classic style, adding prop_cycle to classic style, error handling of invalid properties in batch setting. There is one potential API change. In some areas of the codebase setting an invalid property would result in an AttributeError, while other areas, it raised a TypeError. I right now have it unified as an explicit TypeError, but I could change that back if people think it matters. |
@WeatherGod You managed to fail all of the tests without glaring syntax errors! |
cycler('linestyle', ['-', '--', ':'])) | ||
xs = np.arange(10) | ||
ys = 0.25 * xs**.5 + 2 | ||
ax.fill(xs, ys, label='red, x') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe make the line width thicker in these?
Part of the problem is a difficulty in keeping track of what a Cycler object really is. I guess it is an iterable that returns a sequence of dictionaries, each of which has the same keys. I'm now at a loss as to what to call the mpl factory function, but "cyl" still seems too obscure to me. "dict_sequence" is descriptive, but long and clunky. "kwdicts"? Still unpronounceable. I don't want to make too much of a fuss, but naming does matter for readability and usability. |
I think many of the problems we have API wise are that not enough of a fuss On Fri, Aug 21, 2015 at 4:42 PM Eric Firing notifications@github.com
|
I should note that I would be perfectly ok with leaving the name as |
Keeping the |
I still feel concerned with the name as it feels to generic, where as this function validates specific properties, and thus the name should reflect this specificity... I see that we either need to make the name more specific, e.g |
what about "pcycler()"? Keep in mind that I want to keep this function On Sat, Aug 22, 2015 at 8:37 AM, OceanWolf notifications@github.com wrote:
|
I am losing sight of the original reason for calling the function |
@WeatherGod Completely agree with you on putting such common things together... I started on the beginnings of a branch that does aliasing, but the branch feels very incomplete, nothing like what I feel the final version should look like... but I don't have the time to work on it right now. I saw my fiddlings as something more for 2.x... after we (me and fariza) have gotten MEP22 and MEP27 out of the way. I could push it up as a PR now, but as I say it still needs a lot of work to see if it will go the way I picture it going... |
I vote to dump it in the top level |
Hmm, that might work... this cycler function depends upon validators exposed by rcsetup.py. But since |
no dice... |
Latest Travis errors are weird... in py3k:
Did I miss a memo? |
On Sat, Aug 22, 2015 at 6:17 PM Benjamin Root notifications@github.com
|
oy! you can tell I don't do py3k at my day job... |
Damn, I liked the idea of putting it in |
@OceanWolf, that is a possibility. With my latest updates, |
@OceanWolf, I ended up taking your earlier suggestion of having |
self.set_color_cycle() | ||
self.set_prop_cycle() | ||
|
||
def set_prop_cycle(self, *args, **kwargs): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs a docstring
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, this in on our internal class, not as important as I thought.
ENH: Property Cycling Cycle all artist properties, not just colors
🍻 |
Can also be `None` to reset to the cycle defined by the | ||
current style. | ||
|
||
label : name |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the type supposed to be str
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, it probably should be.
Second attempt at what I am now calling property cycling in order to avoid confusion with style sheets.
It seems to work for line plots, but I know it isn't working for bar plots. I suspect the same is true for errorbar plots. I have some tests unpushed at this point. I want to figure out the failure with bar plots first.