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

Arc Mark / Pie Chart #408

Open
kanitw opened this Issue Apr 7, 2015 · 26 comments

Comments

Projects
None yet
@kanitw
Copy link
Member

kanitw commented Apr 7, 2015

No description provided.

@kanitw kanitw added this to the 1.x (Nice to have later) milestone Apr 7, 2015

@kanitw kanitw modified the milestones: Nice to have, x.x (Should Have Later) May 24, 2015

@marcprux

This comment has been minimized.

Copy link
Contributor

marcprux commented Mar 10, 2016

Is full polar coordinate support required for pie charts? It seems like we could just generate a vega pie transform with the startAngle/endAngle mapped to the color channel.

@kanitw

This comment has been minimized.

Copy link
Member Author

kanitw commented Mar 10, 2016

We might not need to extend Vega for this.

Keep in mind that Vega-Lite is a visualization grammar, we can't add pie support without considering its implication for the underlying coordinate system and other visualizations that could be coherently expressed within the grammar .

We have not spent much time on because pie chart and other polar coordinate based charts generally leads to perceptual issues. In fact, visualization experts generally favor 1D-stacked bar chart to pie charts. So while they might be useful in some cases, we plan to work on other more important features first.

@jsonbecker

This comment has been minimized.

Copy link

jsonbecker commented Feb 2, 2017

I'll thumbs up the desire for this, with my preference being for something like "mark":"pie" or "mark": "donut". I really appreciate the ease of c3 with regards to this kind of transformation, makes it easy to go from stack bar to pie/donut.

@kanitw kanitw changed the title Polar Coordinate Pie Chart / Polar Coordinate Oct 12, 2017

@kanitw kanitw modified the milestones: x.x (Nice to Have), 2.x Visual Encoding Patches Oct 12, 2017

@domoritz domoritz removed the P4-Low label Nov 6, 2017

@mredaelli

This comment has been minimized.

Copy link

mredaelli commented Dec 10, 2017

Having to deal with directional data, I need to plot stuff like this http://gisworld.info/polar-plots-and-circular-statistics-in-arcgis/
For that, would polar coordinates support be required, or can it be done already?

If it cannot, I would recommend changing again the title of the issue (and perhaps reconsider the priority?), because I agree that pie charts are terrible, but for directional statistics polar coordinate support is really necessary :)

@domoritz

This comment has been minimized.

Copy link
Member

domoritz commented Dec 10, 2017

HI @mredaelli. Yes, you'd need polar coordinates and you have to use Vega for now. Unfortunately, we won't add polar coordinates anytime soon and if there is enough need for it, we hope that someone from the community takes on building this feature. We are happy to support anyone who wants to add polar coordinates but don't have the resources ourselves.

@kanitw

This comment has been minimized.

Copy link
Member Author

kanitw commented Dec 11, 2017

Just in case someone want to help implement, I think there are two options going forward for this issue:

a) Making "coordinate" (Cartesian / polar coordinate) a primitive in the language like in ggplot2 and the traditional grammar of graphics.

The benefit for this approach is that it will allow easy transition between stacked bar and pie chart with just operation (just adding a polar coordinate) and this will allow support for many other marks.
However, this will require quite a substantial work in the underlying Vega to make axis and other marks (e.g., line, area) all work for polar coordinate.

b) A bit more compromising approach would be using arc like Vega currently uses.

Although this method won't support all possible plots in polar coordinate, this will require quite way less work -- and probably won't require modifying Vega. Plus, I think it will make spec for pie chart and polar plots a bit more readable. Basically, directly having encoding channel tuples (radius, angle) is more clear than requiring users to know that (x,y) is basically (r,t) / (radius, angle) if polar coordinate is specified.

Thus, IMHO, this might be the way going forward.

Looking at Vega's pie chart example, this can be implemented by adding the following things to Vega-Lite:

  1. New arc mark

  2. New angle and angle2 encoding channel -- only for the arc mark. (for startAngle and endAngle -- but I kinda feel like we should provide a scheme that's consistent with x and x2.)

a) If a field is mapped to angle when there is no field mapped to angle2, this basically represent a pie/donut, there are roughly two options:

  • i) This should automatically populate a pie transform. The encoded field should parameterize the field property of the underlying pie transform and automatically map the output fields from the pie transform to startAngle and endAngle encoding channels in the output Vega spec -- just like how x and y deals with stack stack. For this option, I'm not sure how should sort be based handled since the sort property in the pie transform is just a boolean. Perhaps, we should have some smart logic that uses collect transform if the order encoding channel in VL is specified.
- ii) This can instead populate an equivalent "normalize" stack transform and uses a linear scale that has range from [0, 360]. The channel can have a `stack` property for disable stacking. I personally think this option is better since it still uses a linear scale by default.  Plus, I believe that our logic for sorting the stack would still work.  That said, I think someone should prototype if a pie chart can be created in this way in Vega first. 

b) If both angle and angle2 are provided, we don't need to automatically include pie/stack transform. But we need to determine what's the default scale for this case. (It's not very clear yet.)

  1. new Radius and Radius2 encoding channels (or innerRadius and outerRadius -- but I kinda feel like we should provide a scheme that's consistent with x and x2.) We might not need this for the first MVP PR. (Just making radius and radius2 mark definition can be sufficient for supporting donut and pie.) But this is needed for a nightingale rose diagram.

  2. New padAngle, cornerRadius mark [properties]((https://vega.github.io/vega-lite/docs/mark.html#mark-def) and config.

For each of these channel, we should experiment if we correctly make them work for discrete / continuous scales.

cc: @jheer -- feel free to comment if you have any thoughts :)

@king612

This comment has been minimized.

Copy link

king612 commented Mar 15, 2018

Love 'em or hate 'em, pies and doughnuts are high on the list of things my users ask me for. All the time. Have to support them to get wide adoption of you framework. Ditto transitions btw.

@domoritz

This comment has been minimized.

Copy link
Member

domoritz commented Mar 15, 2018

Transitions are on the roadmap (vega/vega#641). Pie charts require careful design and we will probably rely on external contributions if somebody needs this.

@kanitw

This comment has been minimized.

Copy link
Member Author

kanitw commented Mar 15, 2018

Right now we're focusing more on statistical graphics and annotations, which are way more (uncontroversially) important for adoption in data science/analysis activities.

I agree that people ask for pie and donut all the time, but that doesn't mean that they should always use them. (Yes, there are cases that they are good, but I don't think this is a high priority task for us at the moment. -- We probably do it at some point, but it's not the main priority right now.)

@kanitw kanitw changed the title Pie Chart / Polar Coordinate Arc Mark / Pie Chart Mar 15, 2018

@jwoLondon

This comment has been minimized.

Copy link
Contributor

jwoLondon commented Mar 16, 2018

There is another approach to consider which doesn't involve adding any new grammar and already works in VL 2.3.

Since we now have spherical geographical referencing and map projection onto a plane, we get polar coordinates for free if you represent polar coordinates as longitude/latitude and then project with an azimuthalEquidistant projection rotated to one of the poles.

I used this technique to create the following all in Vega-Lite:

screen shot 2018-03-16 at 23 12 59

I generated the code programmatically with elm-vega which allows me to input a simple list of value-category pairs such as the following:

data =
    toPolar
        [ ( "robin", 4 )
        , ( "sparrow", 6 )
        , ( "wren", 10 )
        , ( "blue tit", 3 )
        , ( "starling", 7 )
        , ( "chaffinch", 8 )
        ]

to generate the necessary longitude/latutude coordinates. So while the resulting Vega-Lite spec below would be a little tedious to write by hand, it should be possible to create a macro to generate the spec as you might for compound statistical graphics.

{
  "$schema": "https://vega.github.io/schema/vega-lite/v2.json",
  "config": { "view": { "stroke": "" } },
  "width": 200, "height": 200,
  "projection": {
    "type": "azimuthalEquidistant", "rotate": [ 0, 90, 0 ]
  },
  "data": {
    "values": {
      "type": "FeatureCollection",
      "features": [
        {
          "type": "Feature",
          "geometry": {
            "type": "Polygon",
            "coordinates": [[[0,90],[37.89,-89],[0,-89],[0,90]]]
          },
          "properties": {"cat": "robin"}
        },
        {
          "type": "Feature",
          "geometry": {
            "type": "Polygon",
            "coordinates": [[[0,90],[94.74,-89],[37.89,-89],[0,90]]]
          },
          "properties": {"cat": "sparrow"}
        },
        {
          "type": "Feature",
          "geometry": {
            "type": "Polygon",
            "coordinates": [[[0,90],[189.47,-89],[94.74,-89],[0,90]]]
          },
          "properties": {"cat": "wren"}
        },
        {
          "type": "Feature",
          "geometry": {
            "type": "Polygon",
            "coordinates": [[[0,90],[217.89,-89],[189.47,-89],[0,90]]]
          },
          "properties": {"cat": "blue tit"}
        },
        {
          "type": "Feature",
          "geometry": {
            "type": "Polygon",
            "coordinates": [[[0,90],[284.215,-89],[217.89,-89],[0,90]]]
          },
          "properties": {"cat": "starling"}
        },
        {
          "type": "Feature",
          "geometry": {
            "type": "Polygon",
            "coordinates": [[[0,90],[360,-89],[284.21,-89],[0,90]]]
          },
          "properties": {"cat": "chaffinch"}
        }
      ]
    },
    "format": {"type": "json","property": "features"}
  },
  "mark": {"type": "geoshape","stroke": "#fff"},
  "encoding": {
    "color": {
      "field": "properties.cat",
      "type": "nominal",
      "legend": {"title": null}
    }
  }
}

One consequence of this approach is that it is trivial to present the same data in a stacked Cartesian plot simply by changing the projection to Equirectangular:

screen shot 2018-03-16 at 23 19 50

Once you create pie charts, donut charts can be created simply by layering a circle of the background colour:

screen shot 2018-03-16 at 22 42 12

And the transformation to polar coordinates allows other polar charts to be created such as 'Nightingale' rose diagrams, here shown with a 'graticule' to provide the radial axes.

screen shot 2018-03-16 at 22 45 50

@domoritz

This comment has been minimized.

Copy link
Member

domoritz commented Mar 17, 2018

That's genius and surprised me as a creator of Vega-Lite.

@kanitw

This comment has been minimized.

Copy link
Member Author

kanitw commented Mar 17, 2018

This is amazing :)

@jakevdp

This comment has been minimized.

Copy link
Collaborator

jakevdp commented Mar 17, 2018

I am impressed. Time for some new Altair examples 😄

@domoritz

This comment has been minimized.

Copy link
Member

domoritz commented Mar 17, 2018

Time for some new Altair examples 😄

This makes me a bit nervous. While the above definitely works, you won't get nice axes or labels. Let's add a warning about this if you want to add these examples. @kanitw we should decide whether we want the pie chart as a test example.

@jakevdp

This comment has been minimized.

Copy link
Collaborator

jakevdp commented Mar 17, 2018

Fair enough, I can hold off. This just looks so cool 😁

@kanitw

This comment has been minimized.

Copy link
Member Author

kanitw commented Mar 17, 2018

you won't get nice axes or labels

You actually get nice grid line (without labels) with this projection approach while the normal arc approach wouldn't. (There is no polar axis support in Vega yet)

That said, I still prefer the arc approach as it will be way easier to comprehend to maintain / reuse the output Vega specs.

(Still the examples are amazing!)

@vega vega deleted a comment from kanitw Mar 17, 2018

@nyurik

This comment has been minimized.

Copy link
Member

nyurik commented Mar 17, 2018

This is awesome! But still a hack :) I wouldn't want to explain to the users how to generate these geodata datasets from their data - imagine someone comes to you and says they have a table data, and they want to draw it as a pie chart - using standard transformations.

@jwoLondon

This comment has been minimized.

Copy link
Contributor

jwoLondon commented Mar 18, 2018

Yes (opaque hack), it was never my intention to encourage people to encode their specs directly in this way. Initially I tried it as a bit of a geeky joke, but then became quite taken with the results. I do think it demonstrates some important points though:

  • If people really need to generate visualisation with polar coords, it is at least technically possible with the current version. In my case I was trying to see if I could reproduce a design I originally wrote with Processing. Personally I am not particularly bothered by the ability to create pie charts, but there are some interesting radial designs that could be more useful.

  • For environments that use higher level languages/interfaces (altair, elm-vega etc.), it allows the creation of an accessible way of generating radial charts of various kinds. I would put them in the same class as Tukey boxplots etc – using Vega-Lite grammar under the hood to create higher level compound graphics.

  • Polar coordinates could be treated in Vega-Lite just like map projections of geo coordinates without making significant changes to the grammar. Of course geo coordinates are polar coordinates, just in 3d, which become 2d polar when projected with an azimuthal projection centred at a pole.

  • I have an interest in the continuum between geospatial and non-geospatial visualization and the spaces that can be created along this continuum so I think it is a useful exercise to push VL to see what can be achieved in those spaces.

@nyurik

This comment has been minimized.

Copy link
Member

nyurik commented Mar 18, 2018

@jwoLondon I agree with you :) It is an interesting approach, and has a number of potentials.. My concern was mostly with geojson portion, because in a sense, you can think of it as using Vega-Lite as a fancy SVG drawing lib. Some data provider does all the heavy lifting of converting data to the visualization's visual aspect (as oppose to outputting just the pure "raw" data) and outputs it as geojson. VL would than simply draw it, without much thought. In a way, this is similar to using Vega's "image" mark - you get the data semi-prepared. The main drawback of this is that Vega spec becomes inseparable from the data generation code on the backend, and that data generation is tightly coupled with the Vega's vis. In a typical Vega scenario, the backend doesn't need to be aware of how the data will be used.

@kanitw

This comment has been minimized.

Copy link
Member Author

kanitw commented Apr 20, 2018

ii) This can instead populate an equivalent "normalize" stack transform and uses a linear scale that has range from [0, 360]. The channel can have a stack property for disable stacking. I personally think this option is better since it still uses a linear scale by default. Plus, I believe that our logic for sorting the stack would still work. That said, I think someone should prototype if a pie chart can be created in this way in Vega first.

Here is an example Vega spec for pie chart using stack transform and a linear scale. I think this approach would work better for Vega-Lite as we can reapply the scale for "angle" for both the case that only angle is defined (automatically generate stack for pie) and the case that both angle and angle2 are defined.

{
  "$schema": "https://vega.github.io/schema/vega/v3.0.json",
  "autosize": "pad",
  "padding": 5,
  "width": 200,
  "height": 21,
  "style": "cell",
  "data": [
    {
      "name": "source_0",
      "url": "data/barley.json",
      "format": {
        "type": "json",
        "parse": {
          "yield": "number"
        }
      },
      "transform": [
        {
          "type": "aggregate",
          "groupby": [
            "site"
          ],
          "ops": [
            "sum"
          ],
          "fields": [
            "yield"
          ],
          "as": [
            "sum_yield"
          ]
        },
        {
          "type": "stack",
          "groupby": [],

          "field": "sum_yield",
          "sort": {
            "field": [
              "site"
            ],
            "order": [
              "descending"
            ]
          },
          "as": [
            "sum_yield_start",
            "sum_yield_end"
          ],
          "offset": "zero"
        }
      ]
    }
  ],
  "marks": [
    {
      "name": "marks",
      "type": "arc",
      "style": [
        "bar"
      ],
      "from": {
        "data": "source_0"
      },
      "encode": {
        "update": {
          "fill": {
            "scale": "color",
            "field": "site"
          },
          "x": {
            "signal": "width/2"
          },
          "y": {
            "signal": "height/2"
          },
          "innerRadius": {"signal": "0"},
          "outerRadius": {"signal": "width / 2"},
          "startAngle": {
            "scale": "angle",
            "field": "sum_yield_end"
          },
          "endAngle": {
            "scale": "angle",
            "field": "sum_yield_start"
          }
        }
      }
    }
  ],
  "scales": [
    {
      "name": "angle",
      "type": "linear",
      "domain": {
        "data": "source_0",
        "fields": [
          "sum_yield_start",
          "sum_yield_end"
        ]
      },
      "range": [
        0,
        {"signal": "2*PI"}
      ],
      "nice": false,
      "zero": true
    },
    {
      "name": "color",
      "type": "ordinal",
      "domain": {
        "data": "source_0",
        "field": "site",
        "sort": true
      },
      "range": "category"
    }
  ],
  "legends": [
    {
      "fill": "color",
      "title": "site",
      "encode": {
        "symbols": {
          "update": {
            "shape": {
              "value": "square"
            }
          }
        }
      }
    }
  ],
  "config": {
    "axisY": {
      "minExtent": 30
    }
  }
}

image

@aishfenton

This comment has been minimized.

Copy link
Contributor

aishfenton commented May 24, 2018

General support for polar visualizations would be useful, something without too much typing required :) If you did add support for pie charts, my vote would be to not bother unless you also support polar area charts, which are much more useful in practice.

@kanitw

This comment has been minimized.

Copy link
Member Author

kanitw commented May 24, 2018

polar area charts

Arc marks can be use to compose radial plots / polar area without the need for a new coordinate system.

However, this won't work with radar chart, etc.

@kanitw

This comment has been minimized.

Copy link
Member Author

kanitw commented Jul 13, 2018

(Copied from slack as @iliatimofeev asks for this feature)

For selection, I actually think that the single and multi selection would come for free (as there is nothing fundamentally different about them). The interval selection is the only bit that’s tricky. However, just like applying interval selection over stacked-bar isn’t meaningful, applying interval selection over polar coordinate isn’t meaningful either. Thus, it shouldn’t be supported.

The question is whether the rest of the team are okay with supporting arc mark at all. If they are okay with that the implementation should be quite straightforward (although it will take some amount of effort).

I’m personally ok if we gonna have this, but I also think that it’s quite lower priority given limited resource we have. So even if the team agree with having this, I don’t plan to do this soon.

@g3o2

This comment has been minimized.

Copy link
Contributor

g3o2 commented Jul 16, 2018

So while the resulting Vega-Lite spec below would be a little tedious to write by hand, it should be possible to create a macro to generate the spec as you might for compound statistical graphics.

Would this be implementable via a dedicated vega-lite transform?

The question is whether the rest of the team are okay with supporting arc mark at all.

As jwoLondon appears to already have "tested" the polar coordinate approach, my guess is that implementing arc can have its own advantages.

@kanitw

This comment has been minimized.

Copy link
Member Author

kanitw commented Jul 16, 2018

As suggested above, this can be done by adding arc mark with angle channel without an additional transform.

Using projection to generate pie chart is an awesome hack but it shouldn't be the official solution if we were to support this at all.

@summerswallow-whi

This comment has been minimized.

Copy link

summerswallow-whi commented Oct 11, 2018

@jwoLondon I would love to see the spec for your "Nightingale" chart. I think it would benefit others.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment