-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Rotate markers in Scatter plot #2478
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
Conversation
if self._sizes.size > self._angles.size: | ||
self._angles = np.ma.resize(self._angles, self._sizes.shape) | ||
else: | ||
self._sizes = np.ma.resize(self._sizes, self._angles.shape) |
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 is different from the behavior of other collection parameters that "wrap around" -- that is, for a given symbol N, the angle would be angles[N % len(angles)]
.
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 is what exactly do np.ma.resize
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.
I don't think it's the same. Here's the current behavior. Say you have 3 sizes (A, B, C) and 2 colors (X, Y), then you get the following combinations:
(A, X)
(B, Y)
(C, X)
I think with the above, you would only get the minimum number of either the sizes or angles.
That said, I think to get this behavior, and be consistent with the other properties, you'll have to extend the backends to understand angles.
@@ -3138,7 +3138,7 @@ def dopatch(xs, ys): | |||
medians=medians, fliers=fliers) | |||
|
|||
@docstring.dedent_interpd | |||
def scatter(self, x, y, s=20, c='b', marker='o', cmap=None, norm=None, | |||
def scatter(self, x, y, s=20, c='b', marker='o', angles=0, cmap=None, norm=None, |
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.
The new kwarg should be at the end to preserve reverse compatibility.
You should not merge master into your working branch, but re-base your branch onto current master. Please remove the merge commit and rebase your commit. |
This needs another rebase and to have a few remaining comments addressed. |
@mgoacolou I have re-milestoned this as 1.5.x as this needs a re-base and we have not heard from you in a few months. If you can get this re-based and fixed up in the near future we can get it in to 1.4.0. |
I'm testing my rebase |
@@ -3469,6 +3472,7 @@ def scatter(self, x, y, s=20, c='b', marker='o', cmap=None, norm=None, | |||
raise ValueError("x and y must be the same size") | |||
|
|||
s = np.ma.ravel(s) # This doesn't have to match x, y in size. | |||
angles = np.ma.ravel(angles) # This doesn't have to match x, y in size. |
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 is one character too long for pep8.
one of the image tests seems to be consistently failing
|
I corrected the bug in computation of scale. The figure (expected and generated) are close but have not the same x/y limites. Is there a way to know why? |
@@ -709,32 +709,121 @@ class _CollectionWithSizes(Collection): | |||
""" | |||
Base class for collections that have an array of sizes. | |||
""" | |||
def __init__(self): |
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 is a major change as sub-class are not guaranteed to call Collections.__init__
because it used to be a no-op (the default) function.
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.
super() guarantees the call of all init and only once if they exists
@mgoacolou any interest in continuing to work on this?
|
@tacaswell Hi, I am now more confident with git now. I'll take a look this week on this. |
apply incrementaly the Affine2D transform for size and angle use super for draw method
oh nice, definitely looking forward to this? so am i correct that after this is in, i can e.g. do: df = pd.DataFrame({X: ..., Y: ..., C: ['Foo', 'Bar', ...]})
marker_map = {'Foo': 'o', 'Bar': 'x'}
plot(df.X, df.Y, marker=[marker_map[c] for c in df.C]) |
No, this is the other meaning of rotate as in 'change the orientation of the marker'. Basically quiver, but with any marker not just arrows. There are deep performance related issue that for k, _df in df.group_by('C'):
ax.plot(_df,X, _df.Y, **style_map[k]) |
is there a more ggplot-like interface to matplotlib? i.e. where you give a DataFrame and column names to seaborn just has its own high-level plots, and pandas’ DataFrame.plot only allows specifying x and y in this way. i basically want to do: |
We are working towards supporting a more robust API like that. You can get On Wed, Mar 23, 2016 at 10:10 AM, Philipp A. notifications@github.com
|
currently, mpl works on a “series-based” level, which imho makes no sense for multidimensional data: you can have one dimension represented by shape, the other by color, the third by size, and two more by x/y position. this results in an exponential number of series. therefore to make sense, your API must deviate from the previous model, and simply track 1. each point individually and 2. each represented feature via legend (marker shape, discrete color), colorbar (continuous color), “volume slider triangle” or axis label (x/y position). like this, but using an isosceles trapezoid as “colorbar for size”: |
color and size should work with scatter + The pandas/table/dataframe/R view of data is not universal or fundamental where as vectors / arrays of number are, hence that is what the core of mpl targets and will continue to target. There is definitely interest from many parties for there to a pandas-aware domain-specific plotting library that lives under the matplotlib gh umbrella organization that can require pandas and do these 'magic' things. The only hold up is developer time. @flying-sheep You have any interest in leading this effort? That said, |
i don’t know if i’m suited, but i’d definitely like to chime in wherever discussion is happening regarding the regarding an universal interface, i disagree: the grammar of graphics is a deconstruction/analysis of the way data visualization happens. and those rules do directly translate into a data frame structure: a heterogeneous collection of feature columns that each carry one entry for each sample. by mapping those feature columns onto graphical features, we get all possible permutations of visualizations. so basically, we have to (implicitly or explicitly) reshape our data into this structure anyway when visualizing it, so we might as well use an interface optimized for this shape (pandas.DataFrame) |
The |
ah, OK, so this ship has sailed then. damn. i submitted #6214 for further discussion |
I am not sure what you mean by "this ship has sailed". All we implemented On Wed, Mar 23, 2016 at 12:27 PM, Philipp A. notifications@github.com
|
... I'm going to close this as abandoned. I'm also not aware that anyone has asked for this functionality for quite a while, and while it looks cool its a significant complication to the code... Feel free to re-open or ask to have it re-opened if I'm closing in error. |
This a re-summit of the #2432
Make possible to give a scalar or an array for rotate markers. This is usefull for representing for example Speed, Type, Direction of mobile targets.