A concise grammar of interactive graphics, built on Vega.

Overview

Vega-Lite

npm version Build Status codecov code style: prettier JSDevlivr

Teaser

Vega-Lite provides a higher-level grammar for visual analysis that generates complete Vega specifications.

You can find more details, documentation, examples, usage instructions, and tutorials on the Vega-Lite website.

Try using Vega-Lite in the online Vega Editor.

Contributions are also welcome. Please see CONTRIBUTING.md for contribution and development guidelines and our Code of Conduct.

Read about future plans in our roadmap.

Team

The development of Vega-Lite is led by the alumni and members of the University of Washington Interactive Data Lab (UW IDL), including Kanit "Ham" Wongsuphasawat (now at Databricks), Dominik Moritz (now at CMU and Apple), Arvind Satyanarayan (now at MIT), and Jeffrey Heer (UW IDL).

Vega-Lite gets significant contributions from its community--in particular Will Strimling, Yuhan (Zoe) Lu, Souvik Sen, Chanwut Kittivorawong, Matthew Chun, Akshat Shrivastava, Saba Noorassa, Sira Horradarn, Donghao Ren, and Halden Lin. Please see the contributors page for the full list of contributors.

Citing Vega-Lite

@article{2017-vega-lite,
  doi = {10.1109/tvcg.2016.2599030},
  year = {2017},
  author = {Arvind Satyanarayan and Dominik Moritz and Kanit Wongsuphasawat and Jeffrey Heer},
  title = {Vega-Lite: A Grammar of Interactive Graphics},
  journal = {{IEEE} Transactions on Visualization \& Computer Graphics (Proc. InfoVis)},
  url = {http://idl.cs.washington.edu/papers/vega-lite},
}
Comments
  • Wrapped facet & wrapped concat / repeat

    Wrapped facet & wrapped concat / repeat

    Current vegalite supports small multiples only on one axis (with row/col similar to Tableau)

    However, it's useful to create wrapped small mutliples (similar to lattice in r / ggplot) http://codealamode.blogspot.com/2012/02/trellis-graphs-in-ggplot2.html

    or this example

    Area - View Composition 
    opened by kanitw 48
  • Reduce redundancy in generated schema

    Reduce redundancy in generated schema

    Some structures in the generated vega-lite-schema.json are repeated multiple times. For example, the timeUnit enumeration is repeated verbatim 13 times throughout the schema. Detecting this redundancy and emitting repeated structures to a shared defs section of the schema would make it much more compact.

    TODO:

    • [x] add enum support to typescript-json-schema
    • [ ] change build process to generate schema using new typescript-json-schema
    • [ ] remove old schema generation process
    opened by marcprux 33
  • Signals in Vega-Lite

    Signals in Vega-Lite

    It would be great to have basic support for signals in Vega-Lite. This could be used to implement a rotating earth as in https://beta.observablehq.com/@domoritz/rotating-earth. Another example would be to define the colors of marks via a signal.

    To implement this, we need to add signal support to the types and fix resulting bugs. Also, as we parse the spec, we need to collect signals and create definitions at the top.

    While this is exciting, we want to be very careful about the design. We don't want to break abstractions or introduce multiple ways to do the same thing. @arvind suggest that we look into how we can extend single selections to support this use case.

    Area - Interaction 
    opened by domoritz 32
  • Support expression for formatting axis

    Support expression for formatting axis

    We already have format types for number and time. We could introduce a flexible expression formatter. This would resolve https://github.com/vega/vega-lite-api/issues/12.

    Related issue: https://github.com/vega/vega/issues/608

    cc @curran

    RFC / Discussion :speech_balloon: Area - Visual Encoding 
    opened by domoritz 31
  • Error bar macro for value + error

    Error bar macro for value + error

    Commonly users come with data of the form value, error. Our errorbar macro should support this use case and not require users to create a transform.

    mark: "errorbar",
    encoding: {
      y: {field: value, type: "quantitative"},
      yError: {field: error, type: "quantitative"}
    }
    
    {
      "data": {
        "values": [
          {
            "yield_error": 3,
            "yield": 32.4,
            "variety": "Glabron"
          },
          {
            "yield_error": 3.2,
            "yield": 30.96667,
            "variety": "Manchuria"
          },
          {
            "yield_error": 1.2,
            "center": 33.966665,
            "variety": "No. 457"
          },
          {
            "yield_error": 2,
            "yield": 30.45,
            "variety": "No. 462"
          }
        ]
      },
      "layer": [
        {
          "mark": "errorbar",
          "encoding": {
            "x": {
              "field": "yield",
              "type": "quantitative",
              "scale": {"zero": false},
              "title": "yield"
            },
            "xError": {"field": "yield_error", "type": "quantitative"},
            "y": {"field": "variety", "type": "ordinal"}
          }
        },
        {
          "mark": {
            "type": "point",
            "filled": true,
            "color": "black"
          },
          "encoding": {
            "x": {
              "field": "yield",
              "type": "quantitative"
            },
            "y": {"field": "variety", "type": "ordinal"}
          }
        }
      ]
    }
    
    Enhancement :tada: RFC / Discussion :speech_balloon: 
    opened by domoritz 31
  • Layers with shared encodings

    Layers with shared encodings

    From reading the documentation it seems like there's not an easy way to have multiple marks share the same encodings without repeating them. For example in this example from the docs:

    {
      "data": {"url": "data/stocks.csv"},
      "layer": [
        {
          "mark": "line",
          "encoding": {
            "x": {"field": "date", "type": "temporal"},
            "y": {"field": "price", "type": "quantitative"},
            "color": {"field": "symbol", "type": "nominal"}
          }
        },
        {
          "mark": "rule",
          "encoding": {
            "y": {
              "field": "price",
              "type": "quantitative",
              "aggregate": "mean"
            },
            "size": {"value": 2},
            "color": {"field": "symbol", "type": "nominal"}
          }
        }
      ]
    }
    

    the color scale is identical between the two layers, and most of the y scale is the same too. To avoid this kind of repetition it would be nice if the layers could "inherit" encodings from the top level, possibly augmenting them along the way:

    {
      "data": {"url": "data/stocks.csv"},
      "encoding": {
        "y": {"field": "price", "type": "quantitative"},
        "color": {"field": "symbol", "type": "nominal"}
      },
      "layer": [
        {
          "mark": "line",
          "encoding": {
            "x": {"field": "date", "type": "temporal"}
          }
        },
        {
          "mark": "rule",
          "encoding": {
            "y": { "aggregate": "mean" },
            "size": {"value": 2}
          }
        }
      ]
    }
    
    Help Wanted Area - Macro / Composite Mark 
    opened by pelotom 27
  • Setting only `width` when using `autosize: fit` should not use default height in compiled Vega

    Setting only `width` when using `autosize: fit` should not use default height in compiled Vega

    See the compiled Vega from this example. The height is set the default config.view.height of 200, but I'd expect this chart to only "fit" the width (since that is all I specified).

    To solve this, I imagine there are two options:

    1. We should not apply the config's height or width when using "autosize": "fit" with one of the dimensions specified.
    2. We allow for some value of "autosize" that specifies only to "fit" along one dimension.
    Bug :bug: Enhancement :tada: Area - Visual Encoding 
    opened by willium 25
  • Consider supporting Filter Object

    Consider supporting Filter Object

    @jheer @domoritz

    Currently our filter is using Vega Expression, which is easy for compilation and manual writing, but not easy for static analysis / enumeration. This will make implementing UI in Polestar / Enumerating in Compass(QL) much easier.

    Should we bring back the support for filter in an object form? I remember we briefly discuss about this in a meeting with @jheer (like in two sentences).

    Now that I think more about CompassQL syntax (and Polestar UI) ... maybe it makes sense to consider it even more closely.

    For example, the following filter

    transform: {
      filter: {
        operator: '<',
        operand1:  {field: 'horsepower'}   // alternative names left / x1/ l
        operand2: {value: 9}               // alternative names right / x2 / r
      }
    } 
    

    might get compiled into transform: {filter: 'datum.horsepower < 9'}.

    In some sense, this syntax proposed syntax is more consistent with how we design FieldDefs.

    If we want to, we can support 'and' and 'or' like this:
    (This is useful for Polestar, but I don't think we really need it for CompassQL and our new UI prototype.)

    transform: {
      filter: {
        and/or: [
           filter1,  // same syntax as above
           filter2
        ] 
      }
    } 
    

    Basically here are the TS interfaces.

    interface BinaryPredicate {
      operator: '<' | '>' | '==' | ...,
      operand1: FieldDef,
      operand2: FieldDef
    }
    
    interface UnaryPredicate {
      operator: ...,   // do we need any unary predicate?
      operand: FieldDef
    }
    
    interface And/OrFilter { // there are two separate interfaces
      and/or: Filter[]
    }
    
    interface NotFilter {
      not: Filter
    }
    
    type Filter = UnaryPredicate | BinaryPredicate | And/OrFilter | NotFilter | string;  // string = expression
    
    RFC / Discussion :speech_balloon: 
    opened by kanitw 24
  • Post aggregation calculation & filter

    Post aggregation calculation & filter

    I'd like to use transform > calculate feature with aggregated fields.

    For example,
    I'm using a simple data set which includes "Status", "Gender", "Department", "Count". What I want to do is calculating "Acceptance Rate" of each "Gender" and "Department".

    The query will looks like below

    SELECT Gender
        , Department
        , sum( case when Status = 'Admit' then Count else 0 end)*1.0  / sum( Count ) * 100 Acceptance_Rate
    FROM admission 
    GROUP BY Gender,  Department
    

    If I can use some aggregated fields to express calculate I can substitute the above query like the below.

    {
      "transform": {
        "calculate": [
          {
            "field": "Acceptance_Rate",
            "expr": "datum.Count / aggregated.sum(datum.Count).by(datum.Department, datum.Gender)"
          }
        ]
      }
    ...
    }
    
    

    (I talked about this issue with @kanitw and it seems not supporting currently.)

    opened by yhoonkim 24
  • Support pre-binned data

    Support pre-binned data

    From an earlier conversation with @domoritz, supporting pre-binned data would be useful for connecting with database. I think this would be useful for @leibatt as well.

    From the conversation, the tricky part is how to know the bin step.

    I wonder if we should just let users input the step in such case?

    opened by kanitw 22
  • JavaScript Syntax for Vega-Lite (similar to Altair)

    JavaScript Syntax for Vega-Lite (similar to Altair)

    Shared on slack by @jheer.

    The refereneces are with regard to the Vega-Lite Infovis paper.

    /// FIGURE 2
    var weather = vl.data()
      .url('data/weather.csv')
      .format('csv');
    
    // Line chart with aggregation
    var fig2a = vl.line()
      .data(weather)
      .x(vl.month('date'))
      .y(vl.mean('temp_max'))
      .color(vl.field('location').type(vl.Nominal));
    // fig2a.toJSON() --> generate Vega-Lite JSON
    
    // Correlation between wind and temperature
    var fig2b = vl.point()
      .data(weather)
      .x(vl.bin('temp_max'))
      .y(vl.bin('wind'))
      .size(vl.count())
      .color(vl.field('location').type(vl.Nominal));
    
    // Stacked bar chart of weather types
    var fig2c = vl.bar()
      .data(weather)
      .x(vl.field('location').type(vl.Nominal));
      .y(vl.count())
      .color(vl.field('weather').type(vl.Nominal));
    
    /// FIGURE 3
    var seattleWeather = vl.data()
      .url('data/weather.csv')
      .format('csv')
      .filter('datum.location === "Seattle"');
    
    var noGrid = vl.axis().grid(false);
    
    // Dual axis layered chart
    var fig3a = vl.layers()
      .add(vl.bar()
        .data(seattleWeather)
        .x(vl.month('date'))
        .y(vl.mean('precipitation').axis(noGrid))
        .color(vl.value('#77b2c7')))
      .add(vl.line()
        .data(seattleWeather)
        .x(vl.month('date'))
        .y(vl.mean('temp_max').axis(noGrid))
        .color(vl.value('#ce323c"}')))
      .resolve(vl.resolve().y('independent'));
    
    var fig3b = vl.vconcat()
      .add(fig2a)
      .add(vl.point()
        .data(weather.copy()
          .filter('datum.precipitation > 0'))
        .x(vl.count())
        .y(vl.field('location').type(vl.Nominal))
        .color(vl.year('date')));
    
    /// FIGURE 4
    
    // Faceted charts
    var fig4a = vl.facet(fig2a)
      .column(vl.field('location'));
    var fig4a = vl.facet()
      .column(vl.field('location'))
      .spec(fig2a);
    
    // Repeated charts
    var fig4b = vl.repeat(fig2a.copy().y(vl.mean(vl.column)))
      .column(['temp_max', 'precipitation']);
    var fig4b = vl.repeat()
      .column(['temp_max', 'precipitation'])
      .spec(fig2a.copy().y(vl.mean(vl.column)));
    
    /// FIGURE 5
    var cars = vl.data().url('data/cars.json');
    
    var scatter = vl.circle()
      .x(vl.field('Horsepower').type(vl.Q))
      .y(vl.field('MPG').type(vl.Q))
      .color(vl.rule()
        .if('id', vl.field('Origin').type(vl.N))
        .else(vl.value('grey')))
      .size(vl.value(100));
    
    // Highlight a single point on click
    var fig5a = scetter.copy()
      .select('id', vl.single());
    
    // Highlight a list of individual points
    var fig5b = scatter.copy()
      .select('id', vl.multi().toggle(true));
    
    // "Paintbrush": highlight multiple points on hover
    var fig5c = scatter.copy()
      .select('id', vl.multi().on('mouseover').toggle(true));
    
    // Highlight a single Origin
    var fig5d = scatter.copy()
      .select('id', vl.single().fields('Origin'));
    
    // Highlight a list of Origins
    var fig5e = scatter.copy()
      .select('id', vl.multi().toggle(true).fields('Origin'));
    
    /// FIGURE 6
    
    // Rectangular brush
    var fig6a = vl.circle()
      .x(vl.field('Horsepower').type(vl.Q))
      .y(vl.field('MPG').type(vl.Q))
      .color(vl.rule()
        .if('region', vl.field('Origin').type(vl.N))
        .else(vl.value('grey')))
      .size(vl.value(100))
      .select('region', vl.interval());
    
    // Moving the brush
    var fig6b = fig6a.copy()
      .select('region', vl.interval().translate(true));
    
    // Single-dimension brush
    var fig6c = fig6a.copy()
      .select('region', vl.interval().translate(true).channels('x'));
    
    /// FIGURE 7
    var fig7 = fig6a.copy()
      .select('region', vl.interval()
        .on('[mousedown[event.shiftKey], mouseup] > mousemove'))
      .select('grid', vl.interval()
        .scales(true)
        .zoom(true)
        .translate('[mousedown[!event.shiftKey], mouseup] > mousemove'));
    
    /// FIGURE 8
    
    // A Single Brush, and Panning & Zooming in a Scatterplot Matri
    var fig8a = vl.repeat()
      .row(['Displacement', 'Miles_per_Gallon'])
      .column(['Displacement', 'Miles_per_Gallon'])
      .spec(vl.circle()
        .data(cars)
        .x(vl.field(vl.column).type(vl.Q))
        .y(vl.field(vl.row).type(vl.Q))
        .color(vl.rule()
          .if('region', vl.field('Origin').type(vl.N))
          .else(vl.value('grey')))
        .size(vl.value(100))
        .select('region', vl.interval()
          .translate(true).zoom(true).resolve('single')
          .on('[mousedown[event.shiftKey], mouseup] > mousemove'))
        .select('grid', vl.interval()
          .scales(true).zoom(true).resolve('single')
          .on('[mousedown[!event.shiftKey], mouseup] > mousemove')));
    
    // Independent Brushes
    var fig8b = fig8a.copy();
    fig8b.spec().select('region').resolve('independent');
    fig8b.spec().select('grid').resolve('independent');
    
    // Unioned Brushes
    var fig8c = fig8a.copy();
    fig8c.spec().select('region').resolve('union');
    fig8c.spec().select('grid').resolve('union');
    
    // Intersected Brushes
    var fig8d = fig8a.copy();
    fig8d.spec().select('region').resolve('intersect');
    fig8d.spec().select('grid').resolve('intersect');
    
    /// FIGURE 9
    var stocks = vl.data.url('data/sp500.csv').format('csv');
    
    // Overview + Detail
    var fig9a = vl.vconcat([
      vl.area()
        .x(vl.field('date').type(vl.T))
        .y(vl.field('price').type(vl.Q))
        .select('region', vl.interval().channels('x'))
        .height(100),
      vl.area()
        .x(vl.field('date').type(vl.T))
        .y(vl.field('price').type(vl.Q)
             .scale(vl.scale().domain(vl.selection('region'))))
        .height(300)
    ]);
    
    // Index Chart
    var fig9b = vl.layers([
      vl.line()
        .data(stocks.copy()
          .lookup('index', vl.selection('indexPt').keys('symbol'))
          .calculate('field', 'indexed_price')
          .calculate('expr', '(datum.price - datum.index.price) / datum.index.price'))
        .x(vl.field('date').type(vl.Temporal))
        .y(vl.field('indexed_price').type(vl.Quantitative))
        .color(vl.field('symbol').type(vl.Nominal))
        .select('indexPt', vl.single()
          .on('mousemove').fields('date').nearest(true)),
      vl.rule()
        .x(vl.selection('indexPt.date').type(vl.T))
        .color(vl.value('red'))
    ]);
    
    /// FIGURE 10
    var flights = vl.data().url('data/flights-2k.json');
    
    var fig10 = vl.repeat()
      .column(['hour', 'delay', 'distance'])
      .spec(vl.bar()
        .data(flights.copy().filter(vl.selection('region')))
        .x(vl.bin(vl.column))
        .y(vl.count())
        .color(vl.value('steelblue'))
        .select('region', vl.interval()
          .channels('x').resolve('intersect_others')));
    
    /// FIGURE 11
    
    // Single-Point Layered Cross Filtering
    var fig11a = vl.repeat()
      .column(['hour', 'delay', 'distance'])
      .spec(vl.layers([
        vl.bar()
          .data(flights)
          .x(vl.bin(vl.column))
          .y(vl.count())
          .color(vl.value('steelblue'))
          .select('selectedBins', vl.single().on('mousemove').channels('x')),
        vl.bar()
          .data(flights.copy().filter(vl.selection('selectedBins')))
          .x(vl.bin(vl.column))
          .y(vl.count())
          .color(vl.value('goldenrod'))
      ]);
    
    // Multi-Point Layered Cross Filtering
    var fig11b = vl.repeat()
      .column(['hour', 'delay', 'distance'])
      .spec(vl.layers([
        vl.bar()
          .data(flights)
          .x(vl.bin(vl.column))
          .y(vl.count())
          .color(vl.value('steelblue'))
          .select('selectedBins', vl.multi().on('click').channels('x')),
        vl.bar()
          .data(flights.copy().filter(vl.selection('selectedBins')))
          .x(vl.bin(vl.column))
          .y(vl.count())
          .color(vl.value('goldenrod'))
      ]);
    
    // Continuous Layered Cross Filtering
    var fig11b = vl.repeat()
      .column(['hour', 'delay', 'distance'])
      .spec(vl.layers([
        vl.bar()
          .data(flights)
          .x(vl.bin(vl.column))
          .y(vl.count())
          .color(vl.value('steelblue'))
          .select('selectedBins', vl.interval().channels('x')),
        vl.bar()
          .data(flights.copy().filter(vl.selection('selectedBins')))
          .x(vl.bin(vl.column))
          .y(vl.count())
          .color(vl.value('goldenrod'))
      ]);
    

    cc @mbostock

    opened by domoritz 22
  • Custom formatters with temporal type

    Custom formatters with temporal type

    Issue Custom formatters with type temporal renders unexpectedly. Warn: "Infinite extent for field '__count': [Infinity, -Infinity]"

    Example Codepen

    Versions vega 5.22.1 vega-lite 5.5.0 vega-embed 6.21.0

    Spec

    {
      "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
      "config": {
        "customFormatTypes": true,
      },
      "width": 600,
      "height": 100,
      "data": {
        "values": [
          { "date": "2022-03-16" },
          { "date": "2022-04-16" },
          { "date": "2022-05-16" },
        ]
      },
      "mark": "bar",
      "encoding": {
        "x": {
          "field": "date",
          "type": "temporal",
          "axis": {
            "formatType": "customFormatter",
          },
        },
        "y": {
          "aggregate": "count",
        },
      },
    }
    

    Context: Should work fine if temporal data is epoch time

    Bug :bug: 
    opened by danielmalaton 0
  • Bug: chart seems to incorrectly label single data entry value with a decimal point

    Bug: chart seems to incorrectly label single data entry value with a decimal point

    Please:

    • [x] Check for duplicate issues. Please file separate requests as separate issues.
    • [x] Describe how to reproduce the bug.
    • [x] Use the latest versions of Vega and Vega-Lite. - using latest version of altair
    • [x] Provide an minimal, reproducible example spec in JSON, wrapped by triple backticks like this:
    {
      "$schema": "https://vega.github.io/schema/vega-lite/v4.17.0.json",
      "data": {"name": "data-0c37a591ceae41251602063922514f84"},
      "datasets": {
        "data-0c37a591ceae41251602063922514f84": [
          {
            "day": "2022-04-01T00:00:00",
            "metric": "Nodulation of legumes",
            "sample": "Arch Field: Hedge",
            "value_float": 0.5
          },
          {
            "day": "2022-07-27T00:00:00",
            "metric": "Nodulation of legumes",
            "sample": "Arch Field: Hedge",
            "value_float": 0.5
          }
        ]
      },
      "layer": [
        {
          "encoding": {
            "detail": {"field": "sample", "type": "nominal"},
            "opacity": {
              "condition": {"selection": "selector001", "value": 1},
              "value": 0.1
            },
            "x": {
              "axis": {"format": "%b %d", "title": null},
              "field": "day",
              "type": "temporal"
            },
            "y": {
              "axis": {"title": "Nodulation of legumes"},
              "field": "value_float",
              "scale": {"zero": false},
              "type": "quantitative"
            }
          },
          "mark": "line",
          "selection": {
            "selector001": {
              "bind": "legend",
              "fields": ["sample"],
              "toggle": "true",
              "type": "multi"
            }
          }
        },
        {
          "encoding": {
            "color": {"field": "sample", "type": "nominal"},
            "detail": {"field": "sample", "type": "nominal"},
            "opacity": {
              "condition": {"selection": "selector001", "value": 1},
              "value": 0.1
            },
            "tooltip": [
              {"field": "sample", "title": "Soil sample", "type": "nominal"},
              {"field": "day", "title": "Date", "type": "temporal"},
              {"field": "value_float", "title": "Value", "type": "quantitative"}
            ],
            "x": {"field": "day", "type": "temporal"},
            "y": {
              "field": "value_float",
              "scale": {"zero": false},
              "type": "quantitative"
            }
          },
          "mark": {"opacity": 1, "size": 50, "type": "circle"}
        }
      ],
      "title": "",
      "width": "container"
    }
    

    Hello! I have found some strange behaviour when representing a small dataset that includes a single data entry with a decimal point value. Here is a simplified version of the code I have to reproduce the bug:

    
    def get_chart(df, dt_format, y_title):
    	chart_base = alt.Chart(df)
    	
    	line_chart = chart_base.mark_line().encode(
    	    x=alt.X("day", axis=alt.Axis(title=None, format=dt_format)),
    	    y=alt.Y(
    	        "value_float",
    	        axis=alt.Axis(title=y_title),
    	        scale=alt.Scale(zero=False),
    	    ),
    	)
    	
    	chart = alt.layer(line_chart).properties(width="container", title="")
    	
    	return chart.to_json()
    

    The df is:

      day         metric             	sample  				value_float
    0 2022-04-01  Nodulation of legumes  Arch Field: Hedge          0.5
    1 2022-07-27  Nodulation of legumes  Arch Field: Hedge          0.5
    

    And the chart looks like this:

    image

    I would expect the scale on the y axis to be labeled 0.5 rather than 1!

    If we try the same code with a slightly bigger dataset, it works as expected.

    df
      day              metric              	sample                value_float
    0 2022-05-06  Nodulation of legumes  Mud Mead: Sample 1          1.5
    1 2022-07-29  Nodulation of legumes  Mud Mead: Sample 1          0.5
    2 2022-08-12  Nodulation of legumes  Mud Mead: Sample 1          0.5
    3 2022-09-28  Nodulation of legumes  Mud Mead: Sample 1          1.5
    4 2022-11-28  Nodulation of legumes  Mud Mead: Sample 1          1.5
    

    image

    I'm not sure if it's relevant to the issue, but I am using a django template the display the chart. Here is the code from the template in case it is relevant:

    <div id="chart" class="vega-plot col-12"></div>
    <script type="text/javascript">
    	window.addEventListener('DOMContentLoaded', function() {
    	  vegaEmbed('#chart', {{ chart|safe }}, {renderer: 'svg'})
    	})
    </script>
    

    Where chart is the chart.to_json() returned above.

    Thanks for your help! Let me know if you need any more information.

    • [] If applicable, include error messages and screenshots, GIF videos (e.g. using https://www.cockos.com/licecap/), or working examples (e.g. by clicking share in the Vega-Editor or https://bit.ly/vega-lite-blocks)
    Bug :bug: 
    opened by taosharma 0
  • chore(deps-dev): bump puppeteer from 15.5.0 to 19.4.1

    chore(deps-dev): bump puppeteer from 15.5.0 to 19.4.1

    Bumps puppeteer from 15.5.0 to 19.4.1.

    Release notes

    Sourced from puppeteer's releases.

    puppeteer-core: v19.4.1

    19.4.1 (2022-12-16)

    Bug Fixes

    • improve a11y snapshot handling if the tree is not correct (#9405) (02fe501), closes #9404
    • remove oopif expectations and fix oopif flakiness (#9375) (810e0cd)

    puppeteer: v19.4.1

    19.4.1 (2022-12-16)

    Miscellaneous Chores

    • puppeteer: Synchronize puppeteer versions

    Dependencies

    • The following workspace dependencies were updated
      • dependencies
        • puppeteer-core bumped from 19.4.0 to 19.4.1

    puppeteer-core: v19.4.0

    19.4.0 (2022-12-07)

    Features

    • ability to send headers via ws connection to browser in node.js environment (#9314) (937fffa), closes #7218
    • chromium: roll to Chromium 109.0.5412.0 (r1069273) (#9364) (1875da6), closes #9233
    • puppeteer-core: keydown supports commands (#9357) (b7ebc5d)

    Bug Fixes

    puppeteer: v19.4.0

    19.4.0 (2022-12-07)

    Features

    Dependencies

    ... (truncated)

    Commits
    • 848c849 chore: release main (#9395)
    • fe986c6 chore: trigger reindexing on doc deployment (#9425)
    • f0951aa docs: use a number of documented versions for indexing (#9424)
    • 68c53df chore(deps): Bump loader-utils from 2.0.2 to 2.0.4 in /website (#9423)
    • 69b03df chore(deps): Bump @​angular-devkit/schematics from 15.0.3 to 15.0.4 (#9420)
    • fa05a1c chore(deps): Bump @​angular-devkit/core from 15.0.3 to 15.0.4 (#9414)
    • 0f0e717 chore(deps): Bump @​angular-devkit/architect from 0.1402.10 to 0.1500.4 (#9415)
    • cd073ab chore(deps): Bump ws from 8.10.0 to 8.11.0 (#9412)
    • cd8eec3 chore(deps): Bump @​angular-devkit/schematics from 14.2.8 to 15.0.3 (#9413)
    • 28cedac chore: Revert Dependabot config (#9411)
    • Additional commits viewable in compare view
    Maintainer changes

    This version was pushed to npm by google-wombot, a new releaser for puppeteer since your current version.


    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    Dependencies :robot: javascript 
    opened by dependabot[bot] 0
  • chore(deps-dev): bump typescript from 4.8.4 to 4.9.4

    chore(deps-dev): bump typescript from 4.8.4 to 4.9.4

    Bumps typescript from 4.8.4 to 4.9.4.

    Release notes

    Sourced from typescript's releases.

    TypeScript 4.9.4

    For release notes, check out the release announcement.

    For the complete list of fixed issues, check out the

    Downloads are available on:

    Changes:

    • e2868216f637e875a74c675845625eb15dcfe9a2 Bump version to 4.9.4 and LKG.
    • eb5419fc8d980859b98553586dfb5f40d811a745 Cherry-pick #51704 to release 4.9 (#51712)
    • b4d382b9b12460adf2da4cc0d1429cf19f8dc8be Cherry-pick changes for narrowing to tagged literal types.
    • e7a02f43fce47e1a39259ada5460bcc33c8e98b5 Port of #51626 and #51689 to release-4.9 (#51627)
    • 1727912f0437a7f367d90040fc4b0b4f3efd017a Cherry-pick fix around visitEachChild to release-4.9. (#51544)

    This list of changes was auto generated.

    TypeScript 4.9

    For release notes, check out the release announcement.

    Downloads are available on:

    Changes:

    • 93bd577458d55cd720b2677705feab5c91eb12ce Bump version to 4.9.3 and LKG.
    • 107f832b80df2dc97748021cb00af2b6813db75b Update LKG.
    • 31bee5682df130a14ffdd5742f994dbe7313dd0e Cherry-pick PR #50977 into release-4.9 (#51363) [ #50872 ]
    • 1e2fa7ae15f8530910fef8b916ec8a4ed0b59c45 Update version to 4.9.2-rc and LKG.
    • 7ab89e5c6e401d161f31f28a6c555a3ba530910e Merge remote-tracking branch 'origin/main' into release-4.9
    • e5cd686defb1a4cbdb36bd012357ba5bed28f371 Update package-lock.json
    • 8d40dc15d1b9945837e7860320fdccfe27c40cad Update package-lock.json
    • 5cfb3a2fe344a5350734305193e6cc99516285ca Only call return() for an abrupt completion in user code (#51297)
    • a7a9d158e817fcb0e94dc1c24e0a401b21be0cc9 Fix for broken baseline in yieldInForInInDownlevelGenerator (#51345)
    • 7f8426f4df0d0a7dd8b72079dafc3e60164a23b1 fix for-in enumeration containing yield in generator (#51295)
    • 3d2b4017eb6b9a2b94bc673291e56ae95e8beddd Fix assertion functions accessed via wildcard imports (#51324)
    • 64d0d5ae140b7b26a09e75114517b418d6bcaa9f fix(51301): Fixing an unused import at the end of a line removes the newline (#51320)
    • 754eeb2986bde30d5926e0fa99c87dda9266d01b Update CodeQL workflow and configuration, fix found bugs (#51263)
    • d8aad262006ad2d2c91aa7a0e4449b4b83c57f7b Update package-lock.json
    • d4f26c840b1db76c0b25a405c8e73830a2b45cbc fix(51245): Class with parameter decorator in arrow function causes "convert to default export" refactoring failure (#51256)
    • 16faf45682173ea437a50330feb4785578923d7f Update package-lock.json
    • 8b1ecdb701e2a2e19e9f8bcdd6b2beac087eabee fix(50654): "Move to a new file" breaks the declaration of referenced variable (#50681)
    • 170a17fad57eae619c5ef2b7bdb3ac00d6c32c47 Dom update 2022-10-25 (#51300)

    ... (truncated)

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    Dependencies :robot: javascript 
    opened by dependabot[bot] 0
  • Order of layering affect bar bandwidth

    Order of layering affect bar bandwidth

    I want to use multiple aggregated tooltips with a box plot, but https://github.com/vega/vega-lite/issues/7918 is preventing me from using the boxplot mark for this so I am building the chart from scratch. I noticed that the order of layering objects changes the bar bandwidth in an unfortunate way. If I put the line under the bar (as desired), there are not spaces between the bars:

    Open the Chart in the Vega Editor

    image

    If the line goes on top, the spaces are there as intended:

    Open the Chart in the Vega Editor

    image

    It feels like a bug to me that this is changed depending on the order of the charts in the layering. Looking at the vega spec, we can see that the first chart has "update": "bandspace(domain('x').length, 0, 0) * x_step"} and the second one has "update": "bandspace(domain('x').length, 0.1, 0.05) * x_step". A workaround is to set "mark": {"type": "bar", "width": {"band": 0.8}},

    Bug :bug: 
    opened by joelostblom 0
Releases(v5.6.1-next.0)
Owner
Vega
Data Visualization Languages & Tools
Vega
An application that allows you to design and test your own stock trading algorithms in an attempt to beat the market.

StockBot is a Python application for designing and testing your own daily stock trading algorithms. Installation Use the

Ryan Cullen 280 Dec 19, 2022
A pandas extension that solves all problems of Jalai/Iraninan/Shamsi dates

Jalali Pandas Extentsion A pandas extension that solves all problems of Jalai/Iraninan/Shamsi dates Features Series Extenstion Convert string to Jalal

51 Jan 02, 2023
PyPassword is a simple follow up to PyPassphrase

PyPassword PyPassword is a simple follow up to PyPassphrase. After finishing that project it occured to me that while some may wish to use that option

Scotty 2 Jan 22, 2022
Fast visualization of radar_scenes based on oleschum/radar_scenes

RadarScenes Tools About This python package provides fast visualization for the RadarScenes dataset. The Open GL based visualizer is smoother than ole

Henrik Söderlund 2 Dec 09, 2021
3D rendered visualization of the austrian monuments registry

Visualization of the Austrian Monuments Visualization of the monument landscape of the austrian monuments registry (Bundesdenkmalamt Denkmalverzeichni

Nikolai Janakiev 3 Oct 24, 2019
Script to create an animated data visualisation for categorical timeseries data - GIF choropleth map with annotations.

choropleth_ldn Simple script to create a chloropleth map of London with categorical timeseries data. The script in main.py creates a gif of the most f

1 Oct 07, 2021
JSNAPY example: Validate NAT policies

JSNAPY example: Validate NAT policies Overview This example will show how to use JSNAPy to make sure the expected NAT policy matches are taking place.

Calvin Remsburg 1 Jan 07, 2022
Data aggregated from the reports found at the MCPS COVID Dashboard into a set of visualizations.

Montgomery County Public Schools COVID-19 Visualizer Contents About this project Data Support this project About this project Data All data we use can

James 3 Jan 19, 2022
Function Plotter: a simple application with GUI to plot mathematical functions

Function-Plotter Function Plotter is a simple application with GUI to plot mathe

Mohamed Nabawe 4 Jan 03, 2022
Visualizations of linear algebra algorithms for people who want a deep understanding

Visualising algorithms on symmetric matrices Examples QR algorithm and LR algorithm Here, we have a GIF animation of an interactive visualisation of t

ogogmad 3 May 05, 2022
GUI for visualization and interactive editing of SMPL-family body models ie. SMPL, SMPL-X, MANO, FLAME.

Body Model Visualizer Introduction This is a simple Open3D-based GUI for SMPL-family body models. This GUI lets you play with the shape, expression, a

Muhammed Kocabas 207 Jan 01, 2023
Time series visualizer is a flexible extension that provides filling world map by country from real data.

Time-series-visualizer Time series visualizer is a flexible extension that provides filling world map by country from csv or json file. You can know d

Long Ng 3 Jul 09, 2021
AB-test-analyzer - Python class to perform AB test analysis

AB-test-analyzer Python class to perform AB test analysis Overview This repo con

13 Jul 16, 2022
GitHubPoster - Make everything a GitHub svg poster

GitHubPoster Make everything a GitHub svg poster 支持 Strava 开心词场 扇贝 Nintendo Switch GPX 多邻国 Issue

yihong 1.3k Jan 02, 2023
Data Visualizer for Super Mario Kart (SNES)

Data Visualizer for Super Mario Kart (SNES)

MrL314 21 Nov 20, 2022
Data Analysis: Data Visualization of Airlines

Data Analysis: Data Visualization of Airlines Anderson Cruz | London-UK | Linkedin | Nowa Capital Project: Traffic Airlines Airline Reporting Carrier

Anderson Cruz 1 Feb 10, 2022
Visualizations of some specific solutions of different differential equations.

Diff_sims Visualizations of some specific solutions of different differential equations. Heat Equation in 1 Dimension (A very beautiful and elegant ex

2 Jan 13, 2022
A deceptively simple plotting library for Streamlit

🍅 Plost A deceptively simple plotting library for Streamlit. Because you've been writing plots wrong all this time. Getting started pip install plost

Thiago Teixeira 192 Dec 29, 2022
This is simply repo for line drawing rendering using freestyle in Blender.

blender_freestyle_line_drawing This is simply repo for line drawing rendering using freestyle in Blender. how to use blender2935 --background --python

MaxLin 3 Jul 02, 2022
A simple project on Data Visualization for CSCI-40 course.

Simple-Data-Visualization A simple project on Data Visualization for CSCI-40 course - the instructions can be found here SAT results in New York in 20

Hugo Matousek 8 Oct 27, 2021