Multiple Pie-Charts summing to 100% accross pie-charts

Viewed 50

I'm using the following vega-lite code to display 2 pie charts at different geo-locations. I'm expecting the pie-charts to be completely filled in (independent), but instead, vega-lite is treating them as one, but plotted in two different places.

I'm trying to plot a small pie chart at the geolocation of each university. The pie chart should show what fraction of people have the "IB" attribute in different states (1 or 0 for this example). The code below has all the data inline. The USA geolocation part is commented out, and the page will load fine, and the problem is in evidence, but if you have the data locally, you can uncomment that section, of course.

{
            "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
            "width": 800,
            "height": 500,
            "projection": {
                "type": "albersUsa"
            },
            "datasets": {
                "uni": [
                    {"name": "UW", "lat": 47.67, "lon": -122.30},
                    {"name": "Yale", "lat": 41.316307, "lon": -72.922585},
                ],
                "people": [
                    {"p_name": "Henry", "uni": "UW", "IB": 1},
                    {"p_name": "Gordon", "uni": "UW", "IB": 1},
                    {"p_name": "Anna", "uni": "UW", "IB": 0},
                    {"p_name": "Shih-Chieh", "uni": "UW", "IB": 0},
                    {"p_name": "Sarah", "uni": "Yale", "IB": 1},
                    {"p_name": "Paul", "uni": "Yale", "IB": 0},
                ]
            },
            "layer": [
                // {
                //     "data": {
                //         "url": "data/us-10m.json",
                //         "format": {
                //             "type": "topojson",
                //             "feature": "states"
                //         }
                //     },
                //     "mark": {
                //         "type": "geoshape",
                //         "fill": "lightgray",
                //         "stroke": "white"
                //     }
                // },
                {
                    "data": { "name": "people"},
                    "transform": [
                        {
                            "lookup": "uni",
                            "from": { "data": {"name": "uni"}, "key": "name", "fields": ["lat", "lon"]},
                        },
                        {
                            "aggregate": [
                                {
                                    "op": "count",
                                    "field:" : "p_name",
                                    "as": "number_people"
                                },
                            ],
                            "groupby": ["uni", "lat", "lon", "IB"]
                        }
                    ],
                    "encoding": {
                        "longitude": {
                            "field": "lon",
                            "type": "quantitative"
                        },
                        "latitude": {
                            "field": "lat",
                            "type": "quantitative"
                        },
                    },
                    "layer": [
                        {
                            "mark": {
                                "type": "circle",
                                "color": "orange",
                            }
                        },
                        {
                            "mark": {
                                "type": "arc",
                                "radius": "10"
                            },
                            "encoding": {
                                "theta": {"field": "number_people", "type": "quantitative"},
                                "color": {"field": "IB", "type": "nominal"},
                            }
                        },
                        {
                            "mark": {
                                "type": "text",
                                "dy": -15
                            },
                            "encoding": {
                                "text": {"field": "uni"}
                            }
                        }
                    ],
                }
            ]
        }

Here is what I get when I have the USA locations uncommented: USA with broken pie-charts

The fractions shown in each piechart are right, but I want the empty white spaces filled in. It is as if the "total" counter needs to be reset for each pie chart.

I'm new to vega-lite, so I may not be approaching this correctly. I've got complete control over the input data, so I can re-organize it into a better form if that makes more sense.

1 Answers

I think I may have a solution for this using transforms.

enter image description here

Editor

{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
  "width": 800,
  "height": 500,
  "projection": {"type": "albersUsa"},
  "datasets": {
    "uni": [
      {"name": "UW", "lat": 47.67, "lon": -122.3},
      {"name": "Yale", "lat": 41.316307, "lon": -72.922585}
    ],
    "people": [
      {"p_name": "Henry", "uni": "UW", "IB": 1},
      {"p_name": "Gordon", "uni": "UW", "IB": 1},
      {"p_name": "Anna", "uni": "UW", "IB": 0},
      {"p_name": "Shih-Chieh", "uni": "UW", "IB": 0},
      {"p_name": "Sarah", "uni": "Yale", "IB": 1},
      {"p_name": "Paul", "uni": "Yale", "IB": 0}
    ]
  },
  "layer": [
    {
      "data": {"name": "people"},
      "transform": [
        {
          "lookup": "uni",
          "from": {
            "data": {"name": "uni"},
            "key": "name",
            "fields": ["lat", "lon"]
          }
        },
        {
          "aggregate": [
            {"op": "count", "field:": "p_name", "as": "number_people"}
          ],
          "groupby": ["uni", "lat", "lon", "IB"]
        },
        {
          "window": [{"op": "sum", "field": "number_people", "as": "total"}],
          "frame": [null, null],
          "groupby": ["uni"]
        },
        {"calculate": "datum.number_people/datum.total * 100", "as": "percent"},
        {
          "stack": "percent",
          "offset": "normalize",
          "as": ["v1", "v2"],
          "groupby": ["uni"]
        },
        {"calculate": "datum.v1 * (2*PI)", "as": "t1"},
        {"calculate": "datum.v2* (2*PI)", "as": "t2"}
      ],
      "encoding": {
        "longitude": {"field": "lon", "type": "quantitative"},
        "latitude": {"field": "lat", "type": "quantitative"}
      },
      "layer": [
        {
          "mark": {
            "type": "arc",
            "radius": 10,
            "theta": {"expr": "datum.t1"},
            "theta2": {"expr": "datum.t2"}
          },
          "encoding": {"color": {"field": "IB", "type": "nominal"}}
        },
        {
          "mark": {"type": "text", "dy": -15},
          "encoding": {"text": {"field": "uni"}}
        }
      ]
    }
  ]
}
Related