Pie chart in vega


{
  "$schema": "https://vega.github.io/schema/vega-lite/v4.json",
  "description": "A simple pie chart with labels.",
  "data": {
    "values": [
      {"category": "a", "value": 4},
      {"category": "a", "value": 4},
      {"category": "c", "value": 4},
      {"category": "d", "value": 0},
      {"category": "e", "value": 4},
      {"category": "f", "value": 4}
    ]
  },
  "transform": [
      {
    "joinaggregate": [{
      "op": "count",
      "field": "category",
      "as": "a_count"
    }],
       "groupby": ["category"]
  },
   
  {
    "joinaggregate": [{
      "op": "sum",
      "field": "value",
      "as": "a_c"
    }],
       "groupby": ["category"]
  },
   

  {
    "calculate": "datum.a_count*datum.a_c",
    "as": "PercentOfTotal"
  }
  ],
  "encoding": {
    "theta": {"field": "PercentOfTotal", "type": "quantitative", "stack": true},
    "color": {"field": "category", "type": "nominal", "legend": null}
  },
  "layer": [{
    "mark": {"type": "arc", "outerRadius": 80}
  }, {
    "mark": {"type": "text", "radius": 90},
    "encoding": {
      "text": {"field": "category", "type": "nominal"}
    }
  }],
  "view": {"stroke": null}
}

Output :

image

Here I wanted to get composition*value of each alphabet in category filed, as I a grouping by category I should get only one a, why am I getting 2 a's in Pie chart and how can I resolve it ?

Thanks for providing the full spec! Your problem is that you are using joinaggregate, which will perform the aggregation and then copy it onto each row. Instead you should use an aggregate with two functions. Here is the working spec:


{
  "$schema": "https://vega.github.io/schema/vega-lite/v4.json",
  "description": "A simple pie chart with labels.",
  "data": {
    "values": [
      {"category": "a", "value": 4},
      {"category": "a", "value": 4},
      {"category": "c", "value": 4},
      {"category": "d", "value": 0},
      {"category": "e", "value": 4},
      {"category": "f", "value": 4}
    ]
  },
  "transform": [
      {
    "aggregate": [{
      "op": "count",
      "field": "category",
      "as": "a_count"
    }, {
      "op": "sum",
      "field": "value",
      "as": "a_c"
    }],
       "groupby": ["category"]
  },   

  {
    "calculate": "datum.a_count*datum.a_c",
    "as": "PercentOfTotal"
  }
  ],
  "encoding": {
    "theta": {"field": "PercentOfTotal", "type": "quantitative", "stack": true},
    "color": {"field": "category", "type": "nominal", "legend": null}
  },
  "layer": [{
    "mark": {"type": "arc", "outerRadius": 80}
  }, {
    "mark": {"type": "text", "radius": 90},
    "encoding": {
      "text": {"field": "category", "type": "nominal"}
    }
  }],
  "view": {"stroke": null}
}

Thank you @wylie

{
  $schema: https://vega.github.io/schema/vega-lite/v4.json
  "config": {"view": {"stroke": ""}},
  width: 600,
data: {
    url: {
      %context%: true
      index: index_dash_dash_slices_slides_decks
      body: {
        size: 10000
        _source: ["mediatype","pred_comp_sem","AgeP","PhotoOfPerson"]
        }
      }
      format: {property: "hits.hits"}
    },
   "transform": [
   {"filter": "datum._source.mediatype == 'Valid Graphic'"},
    {"filter": "datum._source.PhotoOfPerson != '0'"}  
   
   {
    "aggregate": [{
      "op": "count",
      "fields": ["_source.AgeP"],
      "as": ["a_count"]
    }],
     "groupby": ["_source.AgeP"]
  },
  {
  "joinaggregate": [{
      "op": "sum",
      "field": "_source.PhotoOfPerson",
      "as": "ap"
    }],
    "groupby": ["_source.AgeP"]
  },
  {
    "calculate": "datum.a_count" ,
    "as": "PercentOfTotal"
  }
  
   ],
"encoding": {
    "theta": {"field": "PercentOfTotal", "type": "quantitative","format": ".0f","stack": true},
    "color": {
  "field": "_source.AgeP", "type": "nominal"
      },
  },
  "layer": [
  {
    "mark": {
    "type": "arc", "innerRadius": 60,"outerRadius": 100,"padAngle":0,"radius2" : 25}
    },
    {
    "mark": {"type": "text", "radius": 120},
    "encoding": {
      "text": {"field": "_source.AgeP", "type": "nominal"}
    }
  }
 ]
}

Output :

@wylie I have used aggregate and join aggregate functions in the above code, due to which I am getting can't read error.

If I use aggregate for both of them as u have mentioned in above spec, I am getting the sum of PhotoOfPerson as 0, in case of joinaggregate I will get right value for sum, but I am facing above error. May I know how can I resolve this.

@Pranusha119 can you provide an example with data that we can test in the online Vega editor?

  "$schema": "https://vega.github.io/schema/vega-lite/v4.json",
  "description": "A simple pie chart with labels.",
  "data": {
    "values": [
      {"category": "a", "value": 1},
      {"category": "a", "value": 1},
      {"category": "d", "value": 1},
      {"category": "d", "value": 1},
      {"category": "e", "value": 1},
      {"category": "f", "value": 1}
    ]
  },
  "transform": [
  {
    "aggregate": [{
      "op": "count",
      "field": "category",
      "as": "a_count"
    },{
      "op": "mean",
      "field": "value",
      "as": "a_sum"
    }],
      "groupby": ["category"]
  },

  {
    "calculate": "datum.a_count*datum.a_sum",
    "as": "PercentOfTotal"
  }
  ],
  "encoding": {
    "theta": {"field": "PercentOfTotal", "type": "quantitative", "stack": true},
    "color": {"field": "category", "type": "nominal", "legend": null}
  },
  "layer": [{
    "mark": {"type": "arc", "outerRadius": 80}
  }, {
    "mark": {"type": "text", "radius": 90,"fontSize":20},
    "encoding": {
      "text": {"field": "category", "type": "nominal"}
    }
  },
    {
    "mark": {"type": "text", "radius": 120,"fontSize":20},
    "encoding": {
      "text": {"field": "PercentOfTotal", "type": "nominal"}
    }
  }],
  "view": {"stroke": null}
}

Output :

image

On using sample data I am getting correct output.

{
  $schema: https://vega.github.io/schema/vega-lite/v4.json
  "config": {"view": {"stroke": ""}},
width: 600,
data: {
    url: {
      %context%: true
      index: index_dash_dash_slices_slides_decks
      body: {
        size: 10000
        _source: ["mediatype","pred_comp_sem","AgeP","PhotoOfPerson"]
        }
      }
      format: {property: "hits.hits"}
    },
   "transform": [
   {"filter": "datum._source.mediatype == 'Valid Graphic'"},
    {"filter": "datum._source.PhotoOfPerson == 1"},
   {
    "aggregate": [{
      "op": "count",
      "field": "_source.AgeP",
      "as": "a_count"
    },{
      "op": "mean",
      "field": "_source.PhotoOfPerson",
      "as": "ap"
    }],
    "groupby": ["_source.AgeP"]
  },
  {
    "calculate": "datum.a_count*datum.ap" ,
    "as": "PercentOfTotal"
  }
  
   ],
"encoding": {
    "theta": {"field": "PercentOfTotal", "type": "quantitative","format": ".0f","stack": true},
    "color": {
  "field": "_source.AgeP", "type": "nominal"
      },
  },
  "layer": [
  {
    "mark": {
    "type": "arc", "innerRadius": 60,"outerRadius": 100,"padAngle":0,"radius2" : 25}
    },
    {
    "mark": {"type": "text", "radius": 120},
    "encoding": {
      "text": {"field": "_source.AgeP", "type": "nominal"}
    }
  }
 ]
}

Output:

Same code I have used for my data, It's giving an error.

Data:

May I know why it's giving error.

Okay, I have a suggestion. It seems very likely that the problem is here:

   "transform": [
   {"filter": "datum._source.mediatype == 'Valid Graphic'"},
    {"filter": "datum._source.PhotoOfPerson == 1"},

What I think would help you is to look at the Vega inspector (which is available in Kibana 7.10) or by the browser console. Type VEGA_DEBUG.vegalite_spec into your browser, and you'll see the actual JSON data that is returned by Elasticsearch.

Hi @wylie

I don't think problem is with the filters, with the same filters I have used joinaggregate function instead of aggregate function, I was getting the output it's just that components were repeating in pie chart due to joinaggregate function.

code with joinaggregate function :

{
  $schema: https://vega.github.io/schema/vega-lite/v4.json
  "config": {"view": {"stroke": ""}},
width: 600,
data: {
    url: {
      %context%: true
      index: index_dash_dash_slices_slides_decks
      body: {
        size: 10000
        _source: ["mediatype","pred_comp_sem","AgeP","PhotoOfPerson"]
        }
      }
      format: {property: "hits.hits"}
    },
   "transform": [
     {"filter": "datum._source.mediatype == 'Valid Graphic'"},
    {"filter": "datum._source.PhotoOfPerson == 1"},
   {
    "joinaggregate": [{
      "op": "count",
      "field": "_source.AgeP",
      "as": "a_count"
    },{
      "op": "mean",
      "field": "_source.PhotoOfPerson",
      "as": "ap"
    }],
    "groupby": ["_source.AgeP"]
  },
  {
    "calculate": "datum.a_count*datum.ap" ,
    "as": "PercentOfTotal"
  }
  
   ],
"encoding": {
    "theta": {"field": "PercentOfTotal", "type": "quantitative","format": ".0f","stack": true},
    "color": {
  "field": "_source.AgeP", "type": "nominal"
      },
  },
  "layer": [
  {
    "mark": {
    "type": "arc", "innerRadius": 60,"outerRadius": 100,"padAngle":0,"radius2" : 25}
    },
    {
    "mark": {"type": "text", "radius": 120},
    "encoding": {
      "text": {"field": "_source.AgeP", "type": "nominal"}
    }
    },
      {
    "mark": {"type": "text", "radius": 150},
    "encoding": {
      "text": {"field": "PercentOfTotal", "type": "nominal"}
    }
  }
 ]
}

Output :

I can't identify the issue without seeing the data. Since you're unwilling to share the output of VEGA_DEBUG.vegalite_spec, you will need to test this out yourself using the online Vega editor. I recommend reading the full docs on aggregate in Vega-Lite to see if there is anything you've missed