Repository navigation
Description
currently specifying an array for color or size, only works for continuous data. using markers and colors mapped to subsets based on categorical data is hard and manual (basically you subset the data in a loop and call plot multiple times).
i thought it would be hard as list-of-string already means something for some parameters (markers and colors can be specified as strings). but there is pandas’ category dtype.
i propose that using a categorical vector for one of these parameters should be automatically mapped to a palette of colors/markers when specified as c or marker.
# with A, B, C, being either categorical or quantitative,
# S being quantitative, and M being categorical
plt.scatter('A', 'B', s='S', c='C', marker='M', data=df)
# of course also works with arrays, and bool acts like categorical data:
plt.scatter(arr[:,0], arr[:,1], c=arr[:,-1] > 0)more palettes than just the colormap
the color palette for categorical data would be plt.rcParams['axes.prop_cycle'].by_key()['color'], the marker palette a new rcParam (maybe?)
those palettes would be cycled if there are too many categories.
legends
- categorical: legend
- discrete: (ordered legend or segmented bar)
- continuous: bar (colorbar for color, isosceles trapezoid for size)
open questions
- are integers treated as quantitiative + discrete (legend containing all separate values) or continuous (bar)
- how to specify if a legend/colorbar/sizebar should created? it makes sense to automatically do it if we use the
data=interface
Activity
flying-sheep commentedon Mar 23, 2016
@WeatherGod said:
flying-sheep commentedon Mar 23, 2016
well, see the open questions and the fact that allowing to use
scatter(marker='ColName', data=...)is a breaking change since the column could be named e.g.'o'…WeatherGod commentedon Mar 23, 2016
Yes, in the face of ambiguity, we resist the temptation to guess. However,
that doesn't mean that the problem can't be solved somehow (flags? other
annotated types? etc.) We are open to solutions to these very real
problems. We just don't want to slap together a haphazard solution that we
would be stuck with and regret later.
We just need someone to have an inspired idea on how to solve it.
On Wed, Mar 23, 2016 at 12:44 PM, Philipp A. [email protected]
wrote:
tacaswell commentedon Mar 23, 2016
We also have a solicitation up for a GSoC student to work on categorical data.
Plotting methods in mpl should never create a color bar or legend, those are (by design) separate steps.
You can pass in a
BoundryNormfor the color mapping which will give discrete colors (and the color bar code will show them as solid chunks).Looping over a groupby does not seem that onerous. It also gives you the flexbility to do any type of plotting in your loop (not just
scatter, exquiver,bar, etc). Thus instead of putting the logic in every plotting function, the user gets to own the complexity of their data reduction (which will always boil down to a numpy array) and then mpl will plot it.The core issue is that if you have a very restricted sort of data (tabular, many columns, lots of categorical) it may make sense to push many of the groupby and aggregation operations down into the plotting. This is my understanding of what people like about ggplot and is definitely the case with
vegalite. When working on https://github.com/ellisonbg/altair the hardest part of translating their spec to be implemented on top of mpl was not the plotting, but sorting out the aggregations/computation aspect of it. Those complexities are what I think MPL should not pick up. One of the reasons for the wide ranging success of mpl is precisely that it stays out (to a large degree, hist and contour are major exceptions) of computation.As I said in the other thread we are very positive on domain specific charting libraries to be built on top of mpl, but the core team does not have the bandwidth (or domain knowledge in many cases) to write them.
flying-sheep commentedon Mar 24, 2016
refactoring the plotting functions to work more grammar-of-graphics-like would manage to do that as well.
currently i guess they skip step 2 and go directly from 1 to 3, leading to duplicate effort, am i right?
jup, i’m not an expert or even advanced there but i also don’t get why that shoud be part of plotting. if anything, plotting should reshape (melt/cast/pivot) the data, not do statistics on it.
providing a specialized set of helpers to do those easily is beside the point
story645 commentedon Jul 18, 2016
@flying-sheep would a colormap dict work, at least partially. I'm thinking of something in the style of ListedColormap:
that would then be auto hooked into colorbars (and could possibly be hooked into legends via a legend_from_cmap helper...). My main qualm with it is that it would have to do both cmap and norm simultaneously, but mcolors handles both the cmap & norm code and everything that takes a cmap arg takes a norm arg, so that may not be much overhead.
flying-sheep commentedon Jul 18, 2016
sounds good!
naught101 commentedon Dec 7, 2017
At the moment, I can run
scatter([0,1,2], [0,1,2], c=[0,1,2]), which results in a nice plot, and I can runscatter([0,1,2], ['A','B','C'], c=[0,1,2]), which also results in a nice plot, with categories atomatically mapped to the y-axis.scatter([0,1,2], [0,1,2], c=['A','B','C'])doesn't work though. It would be really nice if it did, with each category automatically mapped to a colour. That would make things like these questions much easier to answer: https://stackoverflow.com/questions/26139423/plot-different-color-for-different-categorical-levels-using-matplotlib, https://stackoverflow.com/questions/31883097/elegant-way-to-match-a-string-to-a-random-color-matplotlibNot sure if that should be submitted as a separate issue or not.
blalterman commentedon Dec 7, 2017
story645 commentedon Dec 7, 2017
@naught101 the thing that makes it difficult is the reason it's not implemented, namely that it would require extending unit support to all scalermappable objects (so functions like imshow and pcolor and anything else with a colorbar) and then hooking in a way to generate legends off of colormaps. It's definitely on my wishlist for categoricals, but on the backburner while we refine the current implementation.
8 remaining items
mwaskom commentedon Jun 16, 2018
In fact this was recently added to seaborn and will be available in the next release: mwaskom/seaborn#1436
dburkhardt commentedon Feb 6, 2020
I think this functionality has been added at some point.
The following code works as intended:
story645 commentedon Feb 6, 2020
@dburkhardt that data is a float, which should have always worked barring some bugs on pandas series unpacking. Here categorical is used interchangeably with string data types and string datatypes still don't work.
dburkhardt commentedon Feb 6, 2020
I see, this issue is essentially asking for a matplotlib implementation of MATLAB's gscatter: https://www.mathworks.com/help/stats/gscatter.html. So this desired functionality actually goes back >10 years, I think (http://matplotlib.1069221.n5.nabble.com/matplotlib-gscatter-td12596.html).
jklymak commentedon Feb 6, 2020
... note that Matlab put
gscatterinto a domain-specific toolbox.dburkhardt commentedon Feb 6, 2020
Good point @jklymak, but that toolbox, Statistics and Machine Learning, is also where Mathworks put boxplots (https://www.mathworks.com/help/stats/boxplot.html) which are provided in matplotlib (https://matplotlib.org/api/_as_gen/matplotlib.pyplot.boxplot.html).
Either way, I also would make use of this functionality if it did make it's way into matplotlib, but unfortunately my programming skills are not strong enough for me to be confident in implementing it so I can't do much more than +1 the topic.
jklymak commentedon Feb 6, 2020
There is a cost-benefit to this sort of thing. It looks like seaborn has this, which is a more stats-oriented package than matplotlib, so having them maintain it is great. If I were doing this, I'd just do something like the following, which is hardly more work than the proposed interface:
github-actions commentedon Oct 9, 2023
This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!