-
Notifications
You must be signed in to change notification settings - Fork 185
Sort bars! #106
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
Sort bars! #106
Conversation
eb96989
to
ceb00a5
Compare
Yes! Super useful! Just for fun I've tried:
As expected, the second mark encounters a y scale which already has a domain, and is not allowed to sort it differently. This is fine and logical (it's my approach also on setting the projection's extent in Plot.carto), but then I don't really get why we couldn't also have a "sort: as-is" option, where the domain would be in the order the data feeds into it? Also, is this a case in which we'd want to throw an error or a warning of some sort? (These comments are very secondary.) |
Yeah, I agree it’s a little confusing that sort: false will still sort the inferred domain by default in natural order (just not sort the bars). I’ve thought about having a sort property on the channel, too. I may think a little more before landing. |
a8807a8
to
22fff12
Compare
nice! |
I’ve added sort = "input" for indicating that you want the bars to appear in input order. At first I thought it would be more appropriate to put a sort property on the scale definition, e.g., This all seems good for bars, which have a more obvious interpretation of order (by bar length), but I realize now this is only a partial solution to the ordering problem: what if, for example, you want a dot mark to imply an order for an associated ordinal domain? With a bar, one dimension is always ordinal and the other quantitative, but with other marks there’s not always an obvious interpretation of “order”. And strictly speaking, even with bars, barY can have y1 and y2, and barY can be pointing up or down, so, there are other potential ambiguities. Continuing… |
I’m now wondering if this an ordinal domain’s order can be specified as part of the scale definition, but with some way to refer to a specific channel in another mark. For example, instead of: Plot.plot({
marks: [
Plot.barX(alphabet, {x: "frequency", y: "letter", sort: "ascending"})
]
}) maybe you’d say Plot.plot({
y: {
sort: "bar.x2"
},
marks: [
Plot.barX(alphabet, {x: "frequency", y: "letter", name: "bar"})
]
}) which would mean “sort the y-scale’s domain based on the natural ascending order of the associated value in the bar mark’s x2 channel”. Because you need a way to refer to a specific channel on a specific mark. But of course it’s awkward that now you need to give a name to your marks, and also understand the internal implicit mapping from barX’s x channel to x1 and x2. |
Another quick idea, perhaps all marks could take a sort object whose keys are scales and whose values are channel names? Plot.plot({
marks: [
Plot.barX(alphabet, {x: "frequency", y: "letter", sort: {y: "x"}})
]
}) Though you’d need something like Vega-Lite’s Plot.plot({
marks: [
Plot.barX(alphabet, {x: "frequency", y: "letter", sort: {y: "-x"}})
]
}) And Plot.barX would have to remap the "x" to "x2", but that’s certainly doable. |
I'm content with sort = "input" ; with bars we're working on a derived structure (counts by x), so in a way it has simplified the question: we have a map x => count, and we can sort it as-is ("input" or "no sort"), by x (asc or desc), or by count (asc or desc). The only missing piece might be "input reversed". |
I posted the more general alternative approach in #108. Ruminating on that now. Would love feedback. |
Closing in favor of #108. |
If you add sort = true (short for "descending") to Plot.barX or Plot.barY, the bars will now be automatically sorted by their upper value (y sorted by x2, or x sorted by y2, respectively). This can be used in conjunction with the Plot.groupX or Plot.groupY mark.