Skip to content

facet wrap #332

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

Closed
wants to merge 1 commit into from
Closed

facet wrap #332

wants to merge 1 commit into from

Conversation

Fil
Copy link
Contributor

@Fil Fil commented Apr 19, 2021

Capture d’écran 2021-04-19 à 17 21 24
Capture d’écran 2021-04-19 à 17 21 03

fixes #97
fixes #277
supersedes #293
supersedes #101

  • add a rows option (exclusive to columns, or at least yielding priority)
  • auto hiding fx/fy axes
  • remove sorting (done in Order x by y #442)

(I'm giving up on auto facet labels, since there's no good way of deciding where to place them, and they also require changes to the fy padding. This is easier to do with a function mark that places the facet's name where we want. It will be easier even if we pass the facet's name in #501.)

Build: https://observablehq.com/@fil/facet-wrap-332

Note: empty facets is now merged (#516).

@Fil Fil requested a review from mbostock April 19, 2021 15:22
This was referenced Apr 19, 2021
This was referenced May 12, 2021
@martgnz
Copy link
Contributor

martgnz commented May 25, 2021

After talking with @Fil it seems that the rows option actually adjusts the number of columns in the facet. Would be nice if it could be renamed.

@Fil Fil force-pushed the fil/grid-empty-facets branch from 4b456a6 to 06d224e Compare May 25, 2021 19:49
@Fil
Copy link
Contributor Author

Fil commented May 25, 2021

This still needs some work:

@Fil Fil changed the title grid & empty facets facet wrap & empty facets May 25, 2021
@Fil
Copy link
Contributor Author

Fil commented May 25, 2021

image (46)
this image sent by @martgnz clarifies the wording: we have "grid" faceting when it's "x cross y", and "wrap" faceting when the small multiples are against one dimension, but with a flow layout.

@Fil
Copy link
Contributor Author

Fil commented May 25, 2021

maybe it makes sense to adopt a syntax where x + wrap: 4 would replace x === y + columns: 4 (and wrap: true would replace x === y for the automatic choice of number of columns).

@Fil Fil marked this pull request as draft May 25, 2021 21:35
@Fil Fil self-assigned this May 25, 2021
@martgnz
Copy link
Contributor

martgnz commented May 26, 2021

@Fil what do you think about adding an option to change the number of rows as well? Instead of having a generic wrap toggle we could have one called columns and one called rows. Setting any of them to true or a number would adjust the wrapping automatically or manually, and setting both of them should probably error out. This would make the system more flexible and closer to ggplot2.

@Fil
Copy link
Contributor Author

Fil commented May 27, 2021

I have added facet wrapping on facet: x, with the columns: true or columns: 4 option. It allows to sort the facets by "ascending" (default), "input", or "count", similar to #414 (but, for now, this setting is in the "facet" option).

The labels still have to be added by hand with a (clumsy) selectFirst; I'm not sure how to deal with that yet (ideas welcome).

@Fil Fil force-pushed the fil/grid-empty-facets branch from 89c7d08 to 7140c58 Compare July 11, 2021 09:59
@irenedelatorre
Copy link

Hi,

Not sure if this is helpful, but the solution of the facet_wrap (just like in ggplot2) was actually something I was trying to implement the other day. I ended up having two different svgs and having them side by side. But it would be great if there was a way to do this directly from plot.

image

Basically, the groupings are always on the same axis (either x or y) and then you select the number of columns (or rows). Otherwise, the small facets are too wide but not tall enough, or viceversa.

@Fil Fil force-pushed the fil/grid-empty-facets branch from 7140c58 to 568c856 Compare July 21, 2021 09:48
@Fil
Copy link
Contributor Author

Fil commented Jul 21, 2021

@irenedelatorre Thanks for the great example. Here's a remake of your chart https://observablehq.com/@fil/faceted-bar-chart-experimental, made with this pull-request. It's not perfect: for example, the facets’ names are still added "by hand".

The build is published in the notebook https://observablehq.com/@fil/facet-wrap-332

@Fil Fil mentioned this pull request Jul 21, 2021
@irenedelatorre
Copy link

That looks great @Fil !
Is it triggered by columns: true in facet and z: "score" in binX?

@Fil
Copy link
Contributor Author

Fil commented Jul 22, 2021

it's just columns: true; you could also use columns: 2 or rows: 3 etc. Using facet {y: …} makes the distribution start vertically (from top to bottom in the first column, then second column…); if you used facet {x: …} the distribution would start horizontally. The z: score wasn't necessary, I removed it.

@Fil Fil marked this pull request as ready for review July 30, 2021 14:12
@Fil Fil requested a review from mbostock July 30, 2021 14:14
@Fil
Copy link
Contributor Author

Fil commented Aug 19, 2021

sorting facets by x is now addressed in #442 !

@Fil Fil marked this pull request as draft August 19, 2021 17:44
Fil added a commit that referenced this pull request Aug 20, 2021
(subset of #332)
@Fil Fil mentioned this pull request Aug 20, 2021
mbostock pushed a commit that referenced this pull request Aug 20, 2021
(subset of #332)
mbostock added a commit that referenced this pull request Aug 20, 2021
* empty facets
(subset of #332)

* test plots

* filter facetKeys; pull domain up

* where via range

* update snapshots; remove unused import

* call domain once

* remove unused marksIndex

Co-authored-by: Mike Bostock <[email protected]>
@Fil Fil force-pushed the fil/grid-empty-facets branch from 04ad747 to 26a6f1c Compare August 31, 2021 12:11
@Fil Fil changed the title facet wrap & empty facets facet wrap Aug 31, 2021
@Fil Fil marked this pull request as ready for review August 31, 2021 12:16
@Fil
Copy link
Contributor Author

Fil commented Aug 31, 2021

rewritten

now the facets are sorted (in natural order, unless the sort option is used); setting an explicit facet domain needs to be done in the global facet option instead of fx. (fixed)

@fgregg
Copy link

fgregg commented Apr 1, 2022

Really appreciate this PR!

I am still having a bit of a hard time to understand how control the order of facets. For this example, I'd like to sort by the Average of the value within each facet.

https://observablehq.com/d/9cfc9799c1925b91

@enjalot
Copy link

enjalot commented Apr 5, 2022

Really appreciate this PR!

I am still having a bit of a hard time to understand how control the order of facets. For this example, I'd like to sort by the Average of the value within each facet.

https://observablehq.com/d/9cfc9799c1925b91

I'm not sure which value you want to take the average of, but I made a fork that shows how you can use sort: { fx: "y" } to sort the facet's x axis by a channel:
https://observablehq.com/d/78046fb9b3899914

@Fil Fil force-pushed the fil/grid-empty-facets branch from ff239fb to afcccf6 Compare May 16, 2022 13:44
@Fil
Copy link
Contributor Author

Fil commented May 16, 2022

afcccf6 is a complete rewrite against Plot 0.4.3.

@Fil
Copy link
Contributor Author

Fil commented May 30, 2022

here's an example from the community: https://observablehq.com/@osteele/shanghai-lockdown-spring-2022

Copy link
Member

@mbostock mbostock left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the way you’ve implemented wrapping here, where faceting on x means rows from top to bottom, and faceting on y means columns from left to right. 👍

The immediate challenge I see with this approach is that it seems to corrupt the meaning of the fx and fy scales (which can be seen by retrieving the computed scales). In the athletes-sport-facet example, without facet wrapping you get:

fx = ({
    "type": "band",
    "domain": [
        "gymnastics",
        "weightlifting",
        "table tennis",
        "wrestling",
        "shooting",
        "triathlon",
        "hockey",
        "judo",
        "archery",
        "golf",
        "football",
        "badminton",
        "cycling",
        "boxing",
        "equestrian",
        "athletics",
        "rugby sevens",
        "sailing",
        "modern pentathlon",
        "fencing",
        "canoe",
        "aquatics",
        "taekwondo",
        "tennis",
        "handball",
        "rowing",
        "volleyball",
        "basketball"
    ],
    "range": [
        40,
        620
    ],
    "label": "sport",
    "align": 0.5,
    "round": true,
    "paddingInner": 0.1,
    "paddingOuter": 0,
    "bandwidth": 18,
    "step": 20
})
fy = null

With facet wrapping you get

fx = ({
    "type": "band",
    "domain": [],
    "range": [
        40,
        620
    ],
    "align": 0.5,
    "round": true,
    "paddingInner": 0.1,
    "paddingOuter": 0,
    "bandwidth": 133,
    "step": 148
})
fy = ({
    "type": "band",
    "domain": [],
    "range": [
        40,
        620
    ],
    "align": 0.5,
    "round": true,
    "paddingInner": 0.1,
    "paddingOuter": 0,
    "bandwidth": 133,
    "step": 148
})

I guess I don’t know what fx and fy should mean in this scenario, because they’re no longer orthogonal when facet wrapping is applied. I suppose a simple thing we could do is to throw an error if you try to access either of these scales when facet wrapping is in use, and just treat that as undefined? Alternatively… I dunno, maybe fy is still null, but fx defines a range with [x, y] position instead of singular position? That kind of makes sense, though wouldn’t that imply that we’d allow you to set the range of the fx scale the same way when faceting is in use? Or maybe we should just leave the range as undefined and not allow you to set the range of facet scales when column wrapping? (I can’t imagine people will want to set the range explicitly anyway, and they don’t need to since you can achieve the same result by setting the dimensions and margins.)

@mbostock mbostock mentioned this pull request May 31, 2022
@Fil
Copy link
Contributor Author

Fil commented May 31, 2022

superseded by #892

@Fil Fil closed this May 31, 2022
@Fil Fil deleted the fil/grid-empty-facets branch May 31, 2022 12:53
@mbostock mbostock mentioned this pull request Dec 2, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Facet wrapping Hide empty facets?
6 participants