stem has more elements and thus the styling is more complex: You can set the format for line marker and baseline independently: stem([locs,] heads, linefmt=None, markerfmt=None, basefmt=None). It's not canonically clear what format parts stem(a, 'r') should affect. Analogy does not extend to formats 1:1.
The second aspect is default coloring. Stem does not participate in the color cycle. One can argue that it should and that it's a design flaw.
However, please note that the proposed changes would change the look of existing plots. We are very defensive of such changes. Not breaking our users plots has often a higher priority than making the API a bit better. We have a long-term list for future style changes to be considered for a breaking major release (#14331). I've added the color-cycle participation there.
I would guess that most folks calling stem multiple times would prefer it cycle, and most current plots calling it multiple times would manually set the style or color. So I think participating in the colorcycle is a reasonable new feature that won't break very many people. I'm not sure this needs to wait like some of the rest of #14331.
stem has more elements and thus the styling is more complex: You can set the format for line marker and baseline independently: stem([locs,] heads, linefmt=None, markerfmt=None, basefmt=None). It's not canonically clear what format parts stem(a, 'r') should affect. Analogy does not extend to formats 1:1.
stem(a, 'r') should be a shortcut for stem(a, linefmt='r-', markerfmt='ro'), meaning the default colour (C0) should now be red (r). It doesn't sound to me too convoluted.
More precisely, a new attribute colour = 'C0' should replace the string 'C0' above, and such attribute can be modified when passing an array-like and a string as arguments to stem.
The danger of people calling stem multiple times and relying that it does not change color is relatively low. But if stem takes part in the color cycle, it would advance the cycle, so combinations of stem and plot would also change from same color to separate colors. We can discuss in the next dev call whether we dare change that.
Concerning a fmt parameter. We already have an overloaded stem([locs,] heads, ...). Making that stem([locs,] heads, [fmt], ... is a nightmare API-wise. You would need to support stem(locs, heads) and stem(heads, fmt), which means you have to introspect the variables and guess from them what the user could have meant. I strongly suggest not going there. We have some version of that in plot, but it results in quite complicated code, and sometimes we have to cope with real ambiguity.
Currently, matplotlib fights me when I try switching chart types.
I recognize and respect that.
Uniformity is important, but it's only one among multiple aspects to consider when defining the API. We're not making it better by spreading problematic API through the library. If I could design from scratch, I would do a number of things differently. But in reality we have to compromise somewhere between backward-compatibility, consistency, and clean design.
That said, I believe we can balance the aspects here better.
Default: 'C0o', i.e. filled circles with the first color of the color cycle.
to
If markerfmt does not contain a color, take the color from linefmt. If markerfmt does not contain a marker, take 'o'.
Technically, this is a breaking change. But ihink it's rare that people would want to switch the line color, but implicitly keep the markercolor defaulting to 'C0'.
Activity
timhoffm commented on May 24, 2022
Thank you for the feedback.
stem has more elements and thus the styling is more complex: You can set the format for line marker and baseline independently: stem([locs,] heads, linefmt=None, markerfmt=None, basefmt=None). It's not canonically clear what format parts stem(a, 'r') should affect. Analogy does not extend to formats 1:1.
The second aspect is default coloring. Stem does not participate in the color cycle. One can argue that it should and that it's a design flaw.
However, please note that the proposed changes would change the look of existing plots. We are very defensive of such changes. Not breaking our users plots has often a higher priority than making the API a bit better. We have a long-term list for future style changes to be considered for a breaking major release (#14331). I've added the color-cycle participation there.
jklymak commented on May 25, 2022
I would guess that most folks calling stem multiple times would prefer it cycle, and most current plots calling it multiple times would manually set the style or color. So I think participating in the colorcycle is a reasonable new feature that won't break very many people. I'm not sure this needs to wait like some of the rest of #14331.
Atcold commented on May 27, 2022
@jklymak nailed the point regarding the waitlist.
stem(a, 'r') should be a shortcut for stem(a, linefmt='r-', markerfmt='ro'), meaning the default colour (C0) should now be red (r). It doesn't sound to me too convoluted.
matplotlib/lib/matplotlib/axes/_axes.py
Lines 2918 to 2923 in 79f28ec
More precisely, a new attribute colour = 'C0' should replace the string 'C0' above, and such attribute can be modified when passing an array-like and a string as arguments to stem.
timhoffm commented on May 29, 2022
The danger of people calling stem multiple times and relying that it does not change color is relatively low. But if stem takes part in the color cycle, it would advance the cycle, so combinations of stem and plot would also change from same color to separate colors. We can discuss in the next dev call whether we dare change that.
Concerning a fmt parameter. We already have an overloaded stem([locs,] heads, ...). Making that stem([locs,] heads, [fmt], ... is a nightmare API-wise. You would need to support stem(locs, heads) and stem(heads, fmt), which means you have to introspect the variables and guess from them what the user could have meant. I strongly suggest not going there. We have some version of that in plot, but it results in quite complicated code, and sometimes we have to cope with real ambiguity.
Atcold commented on Jun 9, 2022
My point is that, given that
such behaviour should be extended for uniformity.
Currently, matplotlib fights me when I try switching chart types.
The API should be consistent.
That's it.
timhoffm commented on Jun 9, 2022
I recognize and respect that.
Uniformity is important, but it's only one among multiple aspects to consider when defining the API. We're not making it better by spreading problematic API through the library. If I could design from scratch, I would do a number of things differently. But in reality we have to compromise somewhere between backward-compatibility, consistency, and clean design.
That said, I believe we can balance the aspects here better.
plt.stem(y, 'r') is currently valid API and should work (it never did) - fix: Fix passing stem markerfmt positionally when locs are not given #23232
In 3.5 we deprecated kwarg usage of all formatting parameters. In hindsight that is a bit too restrictive. plt.stem(x, y, 'r') should be allowed, in analogy to `plt.plot(x, y, 'r'). - also addressed in Fix passing stem markerfmt positionally when locs are not given #23232
Change the markerfmt - see Default stem marker color follows the linecolor #23233
to
Technically, this is a breaking change. But ihink it's rare that people would want to switch the line color, but implicitly keep the markercolor defaulting to 'C0'.
Atcold commented on Jun 21, 2022
Awesome, thanks. ❤️