View Source Tucan (tucan v0.4.1)

A high level API interface for creating plots on top of VegaLite.

Tucan is an Elixir plotting library built on top of VegaLite, designed to simplify the creation of interactive and visually stunning plots. With Tucan, you can effortlessly generate a wide range of plots, from simple bar charts to complex composite plots, all while enjoying the power and flexibility of a clean composable functional API.

Tucan offers a simple API for creating most common plot types similarly to the widely used python packages matplotlib and seaborn without requiring the end user to be familiar with the Vega Lite grammar.

Features

  • Versatile Plot Types - Tucan provides an array of plot types, including bar charts, line plots, scatter plots, histograms, and more, allowing you to effectively represent diverse data sets.
  • Clean and consistent API - A clean and consistent plotting API similar to matplotlib or seaborn is provided. You should be able to create most common plots with a single function call and minimal configuration.
  • Grouping and Faceting - Enhance your visualizations with grouping and faceting features, enabling you to examine patterns and trends within subgroups of your data.
  • Customization - Customize your plots with ease using Tucan's utilities for adjusting plot dimensions, titles, and themes.
  • Thin wrapper on top of VegaLite - All VegaLite functions can be used seamlessly with Tucan for advanced customizations if needed.
  • Low level API - A low level API with helper functions allow you to modify any part of a VegaLite specification.

Basic usage

All supported plots expect as first argument some data, a VegaLite specification or a binary which is considered a url to some data. Additionally you can use one of the available Tucan.Datasets.

Tucan.scatter(:iris, "petal_width", "petal_length")
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://gist.githubusercontent.com/curran/a08a1080b88344b0c8a7/raw/0e7a9b0a5d22642a06d3d5b9bcbad9890c8ee534/iris.csv"},"encoding":{"x":{"field":"petal_width","scale":{"zero":false},"type":"quantitative"},"y":{"field":"petal_length","scale":{"zero":false},"type":"quantitative"}},"mark":{"fillOpacity":1,"type":"point"}}

Nx support

If :nx is installed as a dependency you can additionally pass directly the data columns as tensors. For example:

x = Nx.linspace(-20, 20, n: 200)
y = Nx.pow(x, 2)

Tucan.lineplot([x: x, y: y], "x", "y", width: 400)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"values":[{"x":-20.0,"y":400.0},{"x":-19.798994064331055,"y":392.0001525878906},{"x":-19.597990036010742,"y":384.0812072753906},{"x":-19.396984100341797,"y":376.24298095703125},{"x":-19.195980072021484,"y":368.48565673828125},{"x":-18.99497413635254,"y":360.8090515136719},{"x":-18.793970108032227,"y":353.21331787109375},{"x":-18.59296417236328,"y":345.69830322265625},{"x":-18.39196014404297,"y":338.2641906738281},{"x":-18.190954208374023,"y":330.91082763671875},{"x":-17.98995018005371,"y":323.6383056640625},{"x":-17.788944244384766,"y":316.446533203125},{"x":-17.587940216064453,"y":309.33563232421875},{"x":-17.386934280395508,"y":302.30548095703125},{"x":-17.185930252075195,"y":295.356201171875},{"x":-16.98492431640625,"y":288.4876403808594},{"x":-16.783920288085938,"y":281.6999816894531},{"x":-16.582914352416992,"y":274.9930419921875},{"x":-16.38191032409668,"y":268.3669738769531},{"x":-16.180904388427734,"y":261.8216552734375},{"x":-15.979899406433105,"y":255.357177734375},{"x":-15.778894424438477,"y":248.9735107421875},{"x":-15.577889442443848,"y":242.67063903808594},{"x":-15.376884460449219,"y":236.44857788085938},{"x":-15.17587947845459,"y":230.30731201171875},{"x":-14.974874496459961,"y":224.2468719482422},{"x":-14.773869514465332,"y":218.26722717285156},{"x":-14.572864532470703,"y":212.36837768554688},{"x":-14.371858596801758,"y":206.55032348632812},{"x":-14.170854568481445,"y":200.81312561035156},{"x":-13.9698486328125,"y":195.15667724609375},{"x":-13.768844604492188,"y":189.58108520507812},{"x":-13.567838668823242,"y":184.08624267578125},{"x":-13.36683464050293,"y":178.67227172851562},{"x":-13.165828704833984,"y":173.33905029296875},{"x":-12.964824676513672,"y":168.08668518066406},{"x":-12.763818740844727,"y":162.91506958007812},{"x":-12.562814712524414,"y":157.82431030273438},{"x":-12.361808776855469,"y":152.81431579589844},{"x":-12.16080379486084,"y":147.88514709472656},{"x":-11.959798812866211,"y":143.0367889404297},{"x":-11.758793830871582,"y":138.26922607421875},{"x":-11.557788848876953,"y":133.58248901367188},{"x":-11.356783866882324,"y":128.97654724121094},{"x":-11.155778884887695,"y":124.45140075683594},{"x":-10.954773902893066,"y":120.00707244873047},{"x":-10.753768920898438,"y":115.64354705810547},{"x":-10.552763938903809,"y":111.36082458496094},{"x":-10.35175895690918,"y":107.1589126586914},{"x":-10.15075397491455,"y":103.03780364990234},{"x":-9.949748992919922,"y":98.99750518798828},{"x":-9.748744010925293,"y":95.03800964355469},{"x":-9.547739028930664,"y":91.15931701660156},{"x":-9.346734046936035,"y":87.36143493652344},{"x":-9.14572811126709,"y":83.64434051513672},{"x":-8.944723129272461,"y":80.00807189941406},{"x":-8.743718147277832,"y":76.45260620117188},{"x":-8.542713165283203,"y":72.97795104980469},{"x":-8.341708183288574,"y":69.58409881591797},{"x":-8.140703201293945,"y":66.27104949951172},{"x":-7.939698219299316,"y":63.0388069152832},{"x":-7.7386932373046875,"y":59.88737487792969},{"x":-7.537688255310059,"y":56.81674575805664},{"x":-7.33668327331543,"y":53.82691955566406},{"x":-7.135678291320801,"y":50.917903900146484},{"x":-6.934673309326172,"y":48.08969497680664},{"x":-6.733668327331543,"y":45.342288970947266},{"x":-6.532663345336914,"y":42.675689697265625},{"x":-6.331658363342285,"y":40.08989715576172},{"x":-6.130653381347656,"y":37.58491134643555},{"x":-5.929648399353027,"y":35.160728454589844},{"x":-5.728643417358398,"y":32.81735610961914},{"x":-5.5276384353637695,"y":30.554786682128906},{"x":-5.326633453369141,"y":28.373023986816406},{"x":-5.125628471374512,"y":26.27206802368164},{"x":-4.924622535705566,"y":24.251907348632812},{"x":-4.7236175537109375,"y":22.312562942504883},{"x":-4.522612571716309,"y":20.454025268554688},{"x":-4.32160758972168,"y":18.676292419433594},{"x":-4.120602607727051,"y":16.979366302490234},{"x":-3.919597625732422,"y":15.363245964050293},{"x":-3.7185935974121094,"y":13.827938079833984},{"x":-3.517587661743164,"y":12.373422622680664},{"x":-3.3165836334228516,"y":10.999727249145508},{"x":-3.1155776977539062,"y":9.70682430267334},{"x":-2.9145736694335938,"y":8.494739532470703},{"x":-2.7135677337646484,"y":7.363450050354004},{"x":-2.512561798095703,"y":6.312966823577881},{"x":-2.3115577697753906,"y":5.343299388885498},{"x":-2.1105518341064453,"y":4.4544291496276855},{"x":-1.9095478057861328,"y":3.6463727951049805},{"x":-1.7085418701171875,"y":2.9191153049468994},{"x":-1.507537841796875,"y":2.272670269012451},{"x":-1.3065319061279297,"y":1.7070256471633911},{"x":-1.1055278778076172,"y":1.2221919298171997},{"x":-0.9045219421386719,"y":0.8181599378585815},{"x":-0.7035179138183594,"y":0.4949374496936798},{"x":-0.5025119781494141,"y":0.25251829624176025},{"x":-0.30150794982910156,"y":0.09090704470872879},{"x":-0.10050201416015625,"y":0.010100655257701874},{"x":0.10050201416015625,"y":0.010100655257701874},{"x":0.30150794982910156,"y":0.09090704470872879},{"x":0.5025119781494141,"y":0.25251829624176025},{"x":0.7035179138183594,"y":0.4949374496936798},{"x":0.9045219421386719,"y":0.8181599378585815},{"x":1.1055278778076172,"y":1.2221919298171997},{"x":1.3065319061279297,"y":1.7070256471633911},{"x":1.507537841796875,"y":2.272670269012451},{"x":1.7085437774658203,"y":2.919121742248535},{"x":1.9095478057861328,"y":3.6463727951049805},{"x":2.110553741455078,"y":4.454437255859375},{"x":2.3115577697753906,"y":5.343299388885498},{"x":2.512563705444336,"y":6.312976360321045},{"x":2.7135677337646484,"y":7.363450050354004},{"x":2.9145736694335938,"y":8.494739532470703},{"x":3.1155776977539062,"y":9.70682430267334},{"x":3.3165836334228516,"y":10.999727249145508},{"x":3.517587661743164,"y":12.373422622680664},{"x":3.7185935974121094,"y":13.827938079833984},{"x":3.919597625732422,"y":15.363245964050293},{"x":4.120603561401367,"y":16.979373931884766},{"x":4.32160758972168,"y":18.676292419433594},{"x":4.522613525390625,"y":20.45403289794922},{"x":4.7236175537109375,"y":22.312562942504883},{"x":4.924623489379883,"y":24.251916885375977},{"x":5.125627517700195,"y":26.272056579589844},{"x":5.326633453369141,"y":28.373023986816406},{"x":5.527637481689453,"y":30.55477523803711},{"x":5.728643417358398,"y":32.81735610961914},{"x":5.929649353027344,"y":35.16073989868164},{"x":6.130653381347656,"y":37.58491134643555},{"x":6.331659317016602,"y":40.089908599853516},{"x":6.532663345336914,"y":42.675689697265625},{"x":6.733669281005859,"y":45.34230041503906},{"x":6.934673309326172,"y":48.08969497680664},{"x":7.135679244995117,"y":50.91791915893555},{"x":7.33668327331543,"y":53.82691955566406},{"x":7.537689208984375,"y":56.81675720214844},{"x":7.7386932373046875,"y":59.88737487792969},{"x":7.939699172973633,"y":63.038822174072266},{"x":8.140703201293945,"y":66.27104949951172},{"x":8.34170913696289,"y":69.58411407470703},{"x":8.542713165283203,"y":72.97795104980469},{"x":8.743719100952148,"y":76.45262145996094},{"x":8.944723129272461,"y":80.00807189941406},{"x":9.145729064941406,"y":83.64436340332031},{"x":9.346733093261719,"y":87.36141967773438},{"x":9.547739028930664,"y":91.15931701660156},{"x":9.748743057250977,"y":95.03799438476562},{"x":9.949748992919922,"y":98.99750518798828},{"x":10.150754928588867,"y":103.03782653808594},{"x":10.35175895690918,"y":107.1589126586914},{"x":10.552764892578125,"y":111.36084747314453},{"x":10.753768920898438,"y":115.64354705810547},{"x":10.954774856567383,"y":120.00709533691406},{"x":11.155778884887695,"y":124.45140075683594},{"x":11.35678482055664,"y":128.9765625},{"x":11.557788848876953,"y":133.58248901367188},{"x":11.758794784545898,"y":138.26925659179688},{"x":11.959798812866211,"y":143.0367889404297},{"x":12.160804748535156,"y":147.8851776123047},{"x":12.361808776855469,"y":152.81431579589844},{"x":12.562812805175781,"y":157.8242645263672},{"x":12.76382064819336,"y":162.9151153564453},{"x":12.964824676513672,"y":168.08668518066406},{"x":13.165828704833984,"y":173.33905029296875},{"x":13.366832733154297,"y":178.67221069335938},{"x":13.567840576171875,"y":184.0863037109375},{"x":13.768844604492188,"y":189.58108520507812},{"x":13.9698486328125,"y":195.15667724609375},{"x":14.170852661132812,"y":200.8130645751953},{"x":14.37186050415039,"y":206.5503692626953},{"x":14.572864532470703,"y":212.36837768554688},{"x":14.773868560791016,"y":218.26719665527344},{"x":14.974876403808594,"y":224.24691772460938},{"x":15.175880432128906,"y":230.30734252929688},{"x":15.376884460449219,"y":236.44857788085938},{"x":15.577888488769531,"y":242.6706085205078},{"x":15.77889633178711,"y":248.97357177734375},{"x":15.979900360107422,"y":255.35720825195312},{"x":16.180904388427734,"y":261.8216552734375},{"x":16.381908416748047,"y":268.3669128417969},{"x":16.582916259765625,"y":274.99310302734375},{"x":16.783920288085938,"y":281.6999816894531},{"x":16.98492431640625,"y":288.4876403808594},{"x":17.185928344726562,"y":295.35614013671875},{"x":17.38693618774414,"y":302.3055419921875},{"x":17.587940216064453,"y":309.33563232421875},{"x":17.788944244384766,"y":316.446533203125},{"x":17.989948272705078,"y":323.63824462890625},{"x":18.190956115722656,"y":330.910888671875},{"x":18.39196014404297,"y":338.2641906738281},{"x":18.59296417236328,"y":345.69830322265625},{"x":18.79397201538086,"y":353.21337890625},{"x":18.994976043701172,"y":360.8091125488281},{"x":19.195980072021484,"y":368.48565673828125},{"x":19.396984100341797,"y":376.24298095703125},{"x":19.597991943359375,"y":384.081298828125},{"x":19.798995971679688,"y":392.000244140625},{"x":20.0,"y":400.0}]},"encoding":{"x":{"field":"x","type":"quantitative"},"y":{"field":"y","type":"quantitative"}},"mark":{"fillOpacity":1,"type":"line"},"width":400}

For more details check Tucan.new/2.

You can apply semantic grouping by a third variable by modifying the color, the shape or the size of the points:

Tucan.scatter(:iris, "petal_width", "petal_length", color_by: "species", shape_by: "species")
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://gist.githubusercontent.com/curran/a08a1080b88344b0c8a7/raw/0e7a9b0a5d22642a06d3d5b9bcbad9890c8ee534/iris.csv"},"encoding":{"color":{"field":"species","type":"nominal"},"shape":{"field":"species","type":"nominal"},"x":{"field":"petal_width","scale":{"zero":false},"type":"quantitative"},"y":{"field":"petal_length","scale":{"zero":false},"type":"quantitative"}},"mark":{"fillOpacity":1,"type":"point"}}

Alternatively you could use the helper grouping functions:

Tucan.scatter(:iris, "petal_width", "petal_length")
|> Tucan.color_by("species")
|> Tucan.shape_by("species")
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://gist.githubusercontent.com/curran/a08a1080b88344b0c8a7/raw/0e7a9b0a5d22642a06d3d5b9bcbad9890c8ee534/iris.csv"},"encoding":{"color":{"field":"species"},"shape":{"field":"species"},"x":{"field":"petal_width","scale":{"zero":false},"type":"quantitative"},"y":{"field":"petal_length","scale":{"zero":false},"type":"quantitative"}},"mark":{"fillOpacity":1,"type":"point"}}

Use the functional API carefully

For some plot types where transformations are applied on the input data it is recommended to use the options instead of the functional API, since in the first case any required grouping will also be applied to the transformations.

Composite plots

Tucan also provides some helper functions for generating composite plots. pairplot/3 can be used to plot pairwise relationships across a dataset.

fields = ["Beak Length (mm)", "Beak Depth (mm)", "Body Mass (g)"]

Tucan.pairplot(:penguins, fields, diagonal: :density)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","columns":3,"concat":[{"encoding":{"x":{"axis":{"title":null},"field":"value","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":"Beak Length (mm)"},"field":"density","stack":null,"type":"quantitative"}},"mark":{"fillOpacity":1,"orient":"vertical","type":"area"},"transform":[{"counts":false,"cumulative":false,"density":"Beak Length (mm)","maxsteps":200,"minsteps":25}]},{"encoding":{"x":{"axis":{"title":null},"field":"Beak Depth (mm)","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"Beak Length (mm)","scale":{"zero":false},"type":"quantitative"}},"mark":{"fillOpacity":1,"type":"point"}},{"encoding":{"x":{"axis":{"title":null},"field":"Body Mass (g)","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"Beak Length (mm)","scale":{"zero":false},"type":"quantitative"}},"mark":{"fillOpacity":1,"type":"point"}},{"encoding":{"x":{"axis":{"title":null},"field":"Beak Length (mm)","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":"Beak Depth (mm)"},"field":"Beak Depth (mm)","scale":{"zero":false},"type":"quantitative"}},"mark":{"fillOpacity":1,"type":"point"}},{"encoding":{"x":{"axis":{"title":null},"field":"value","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"density","stack":null,"type":"quantitative"}},"mark":{"fillOpacity":1,"orient":"vertical","type":"area"},"transform":[{"counts":false,"cumulative":false,"density":"Beak Depth (mm)","maxsteps":200,"minsteps":25}]},{"encoding":{"x":{"axis":{"title":null},"field":"Body Mass (g)","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"Beak Depth (mm)","scale":{"zero":false},"type":"quantitative"}},"mark":{"fillOpacity":1,"type":"point"}},{"encoding":{"x":{"axis":{"title":"Beak Length (mm)"},"field":"Beak Length (mm)","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":"Body Mass (g)"},"field":"Body Mass (g)","scale":{"zero":false},"type":"quantitative"}},"mark":{"fillOpacity":1,"type":"point"}},{"encoding":{"x":{"axis":{"title":"Beak Depth (mm)"},"field":"Beak Depth (mm)","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"Body Mass (g)","scale":{"zero":false},"type":"quantitative"}},"mark":{"fillOpacity":1,"type":"point"}},{"encoding":{"x":{"axis":{"title":"Body Mass (g)"},"field":"value","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"density","stack":null,"type":"quantitative"}},"mark":{"fillOpacity":1,"orient":"vertical","type":"area"},"transform":[{"counts":false,"cumulative":false,"density":"Body Mass (g)","maxsteps":200,"minsteps":25}]}],"data":{"url":"https://raw.githubusercontent.com/vega/vega-datasets/next/data/penguins.json"}}

Customization & Themes

Various methods and helper modules allow you to easily modify the style of a plot.

Tucan.bubble(:gapminder, "income", "health", "population",
  color_by: "region",
  width: 400,
  tooltip: :data
)
|> Tucan.Axes.set_x_title("Gdp per Capita")
|> Tucan.Axes.set_y_title("Life expectancy")
|> Tucan.Scale.set_x_scale(:log)
|> Tucan.Grid.set_color(:x, "red")
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://vega.github.io/vega-datasets/data/gapminder-health-income.csv"},"encoding":{"color":{"field":"region","type":"nominal"},"size":{"field":"population","type":"quantitative"},"x":{"axis":{"gridColor":"red","title":"Gdp per Capita"},"field":"income","scale":{"type":"log","zero":false},"type":"quantitative"},"y":{"axis":{"title":"Life expectancy"},"field":"health","scale":{"zero":false},"type":"quantitative"}},"mark":{"tooltip":{"content":"data"},"type":"circle"},"width":400}

Additionally set_theme/2 allows you to set one of the supported Tucan.Themes.

Tucan.density_heatmap(:penguins, "Beak Length (mm)", "Beak Depth (mm)")
|> Tucan.set_theme(:latimes)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","config":{"arc":{"fill":"#82c6df"},"area":{"fill":"#82c6df"},"axis":{"labelFont":"Benton Gothic, sans-serif","labelFontSize":11.5,"labelFontWeight":"normal","titleFont":"Benton Gothic Bold, sans-serif","titleFontSize":13,"titleFontWeight":"normal"},"axisX":{"labelangle":0,"labelpadding":4,"ticksize":3},"axisY":{"labelbaseline":"middle","maxextent":45,"minextent":45,"ticksize":2,"titlealign":"left","titleangle":0,"titlex":-45,"titley":-11},"background":"#ffffff","legend":{"font":"Benton Gothic, sans-serif","fontSize":11.5,"symboltype":"square","titleFont":"Benton Gothic Bold, sans-serif","titleFontSize":13,"titleFontWeight":"normal"},"line":{"stroke":"#82c6df","strokeWidth":2},"path":{"stroke":"#82c6df"},"range":{"category":["#ec8431","#829eb1","#c89d29","#3580b1","#adc839","#ab7fb4"],"diverging":["#e68a4f","#f4bb6a","#f9e39c","#dadfe2","#a6b7c6","#849eae"],"heatmap":["#fbf2c7","#f9e39c","#f8d36e","#f4bb6a","#e68a4f","#d15a40","#ab4232"],"ordinal":["#fbf2c7","#f9e39c","#f8d36e","#f4bb6a","#e68a4f","#d15a40","#ab4232"],"ramp":["#fbf2c7","#f9e39c","#f8d36e","#f4bb6a","#e68a4f","#d15a40","#ab4232"]},"rect":{"fill":"#82c6df"},"shape":{"stroke":"#82c6df"},"symbol":{"fill":"#82c6df","size":30},"title":{"anchor":"start","color":"#000000","font":"Benton Gothic Bold, sans-serif","fontSize":22,"fontWeight":"normal"}},"data":{"url":"https://raw.githubusercontent.com/vega/vega-datasets/next/data/penguins.json"},"encoding":{"color":{"aggregate":"count","type":"quantitative"},"x":{"bin":true,"field":"Beak Length (mm)","type":"quantitative"},"y":{"bin":true,"field":"Beak Depth (mm)","type":"quantitative"}},"mark":{"fillOpacity":1,"type":"rect"}}

Encoding channels options

All Tucan plots are building a VegaLite specification based on some sane default parameters. Notice that only a tiny subset of vega-lite configuration options are exported in Tucan's public API. This is more than enough in most cases. Additionally, an optional configuration option is added for every encoding channel that is used, that allows you to add any vega-lite option or change the default options set by Tucan.

For example:

Tucan.bar(:weather, "date", "date",
  color_by: "weather",
  tooltip: true,
  x: [type: :ordinal, time_unit: :month],
  y: [aggregate: :count]
)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://vega.github.io/editor/data/weather.csv"},"encoding":{"color":{"field":"weather"},"x":{"axis":{"labelAngle":0},"field":"date","timeUnit":"month","type":"ordinal"},"y":{"aggregate":"count","field":"date","type":"quantitative"}},"mark":{"fillOpacity":1,"tooltip":true,"type":"bar"}}

Custom encoding options and :orient flag

Some plots support the :orient flag which flips the default orientation. Keep in mind that the :orient flag is set then the custom encoding options correspond to the final encoding channels and not the default ones.

For example assume that we want to sort a bar chart by the numerical value. By default a bar chart has a vertical orientation. So we can achieve the sorting by passing the x: [sort: "-y"] option:

data = %{
  "letter" => ["A", "B", "C", "D", "E", "F", "G"],
  "count" => [28, 55, 43, 91, 81, 53, 19]
}

Tucan.bar(data, "letter", "count", x: [sort: "-y"])
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"values":[{"count":28,"letter":"A"},{"count":55,"letter":"B"},{"count":43,"letter":"C"},{"count":91,"letter":"D"},{"count":81,"letter":"E"},{"count":53,"letter":"F"},{"count":19,"letter":"G"}]},"encoding":{"x":{"axis":{"labelAngle":0},"field":"letter","sort":"-y","type":"nominal"},"y":{"field":"count","type":"quantitative"}},"mark":{"fillOpacity":1,"type":"bar"}}

If we want to display the same on a :horizontal orientation we need to pass the sorting options to the :y channel:

data = %{
  "letter" => ["A", "B", "C", "D", "E", "F", "G"],
  "count" => [28, 55, 43, 91, 81, 53, 19]
}

Tucan.bar(data, "letter", "count", y: [sort: "-x"], orient: :horizontal)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"values":[{"count":28,"letter":"A"},{"count":55,"letter":"B"},{"count":43,"letter":"C"},{"count":91,"letter":"D"},{"count":81,"letter":"E"},{"count":53,"letter":"F"},{"count":19,"letter":"G"}]},"encoding":{"x":{"field":"count","type":"quantitative"},"y":{"axis":{"labelAngle":0},"field":"letter","sort":"-x","type":"nominal"}},"mark":{"fillOpacity":1,"type":"bar"}}

Interactive plots

Most tucan plots support zooming and panning. In order to activate them you can set the :zoomable option to true. Use your mouse to zoom and pan the following plot. You can also reset the view with a double click.

Tucan.scatter(:iris, "petal_width", "petal_length", zoomable: true)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://gist.githubusercontent.com/curran/a08a1080b88344b0c8a7/raw/0e7a9b0a5d22642a06d3d5b9bcbad9890c8ee534/iris.csv"},"encoding":{"x":{"field":"petal_width","scale":{"zero":false},"type":"quantitative"},"y":{"field":"petal_length","scale":{"zero":false},"type":"quantitative"}},"mark":{"fillOpacity":1,"type":"point"},"params":[{"bind":"scales","name":"_grid","select":"interval"}]}

Additionally tooltips can be added to the plot by setting the :tooltip option.

Tucan.histogram(:cars, "Horsepower", tooltip: true, zoomable: true)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","__tucan__":{"plot":"histogram"},"data":{"url":"https://vega.github.io/editor/data/cars.json"},"encoding":{"x":{"bin":{"binned":true},"field":"bin_Horsepower","title":"Horsepower"},"x2":{"field":"bin_Horsepower_end"},"y":{"field":"count_Horsepower","stack":null,"type":"quantitative"}},"mark":{"fillOpacity":1,"tooltip":true,"type":"bar"},"params":[{"bind":"scales","name":"_grid","select":"interval"}],"transform":[{"as":"bin_Horsepower","bin":true,"field":"Horsepower"},{"aggregate":[{"as":"count_Horsepower","op":"count"}],"groupby":["bin_Horsepower","bin_Horsepower_end"]}]}

Summary

Construction

Creates an empty VegaLite plot.

Creates if needed a VegaLite plot and adds data to it.

Plots

Returns the specification of an area plot.

Returns the specification of a box plot.

Returns the specification of a bubble plot.

Plot the counts of observations for a categorical variable.

Plot the distribution of a numeric variable.

Draws an error band (confidence interval).

Plots the errorbar for the given numerical variable field.

Returns the specification of a heatmap.

Draw a line plot between x and y

Returns the specification of a punch card plot.

Returns the specification of a scatter plot with possibility of several semantic groupings.

Returns the specification of a step chart.

Returns the specification of a streamgraph.

Draws a strip plot (categorical scatterplot).

Composite Plots

Returns the specification of a jointplot.

Plot pairwise relationships in a dataset.

Images

Display data as an image.

Auxiliary Plots

Adds a text annotation to the given x, y position.

Adds a horizontal line at the given h position.

Adds a vertical or horizontal ruler at the given position.

Adds a vertical line at the given x position.

Layout

Concatenates the given plots.

Concatenates horizontally the given plots.

Creates a layered plot.

Concatenates vertically the given plots.

Grouping

Adds a color encoding for the given field.

Apply facetting on the input plot vl by the given field.

Adds a fill encoding for the given field.

Adds a shape encoding for the given field.

Adds a size encoding for the given field.

Adds a stroke_dash encoding for the given field.

Utilities

Adds a background image to the current plot.

Flips the axes of the provided chart.

Adds a hyperlink encoding.

Styling

Sets the height of the plot (in pixels).

Sets the plot size.

Sets the plot's theme.

Sets the title of the plot.

Sets the width of the plot (in pixels).

Types

A string corresponding to a dataset's field

The plot data.

Construction

@spec new() :: VegaLite.t()

Creates an empty VegaLite plot.

This is a simple wrapper around VegaLite.new/0.

Link to this function

new(plotdata, opts \\ [])

View Source
@spec new(plotdata :: plotdata(), opts :: keyword()) :: VegaLite.t()

Creates if needed a VegaLite plot and adds data to it.

The behaviour of this function depends on the type of plotdata:

  • if a VegaLite.t() struct is passed then it is returned unchanged.
  • If it is a binary it is considered a url and the VegaLite.data_from_url/2 is called on a newly created VegaLite struct.
  • if it is an atom then it is considered a Tucan.Dataset and it is translated to the dataset's url. If the dataset name is invalid an exception is raised.
  • in any other case it is considered a set of data values and the values are set as data to a newly created VegaLite struct. Any tabular data is accepted, as long as it adheres to the Table.Reader protocol.

Examples

Passing a URL to some dataset

Tucan.new("https://vega.github.io/editor/data/penguins.json")
|> ...

Tucan.new("https://vega.github.io/editor/data/stocks.csv", format: :csv)
|> ...

Using a pre-defined Tucan.Dataset

Tucan.new(:penguins)
|> ...

Tucan.new(:iris)
|> ...

Passing directly tabular data

data = [
  %{"category" => "A", "score" => 28},
  %{"category" => "B", "score" => 55}
]

Tucan.new(data)
|> ...

You can also pass individual series:

xs = 1..100
ys = 1..100

Tucan.new(x: xs, y: ys)
|> ...

Any data that adheres to the Table.Reader protocol is accepted, for example you could pass an Explorer.DataFrame

mountains = Explorer.DataFrame.new(
  name: ["Everest", "K2", "Aconcagua"],
  elevation: [8848, 8611, 6962]
)

Tucan.new(mountains)
|> ...

Additionally you can pass Nx.Tensors as series. These will be implicitly transformed to lists.

xs = Nx.linspace(0, 10, n: 100)
ys = Nx.sin(xs)

Tucan.new([x: xs, y: ys])
|> ...

Valid Nx.Tensor shapes

1-dimensional tensors are expected when you pass Nx tensors as series. Additionally for convenience 2-dimensional tensors where one of the two dimensions is 1 are also supported.

For example the following are equivalent

x = Nx.linspace(0, 10, n: 10)
y = Nx.pow(x, 2)

plot1 = Tucan.new(x: x, y: y)

x = Nx.reshape(x, {10, 1})
y = Nx.reshape(y, {1, 10})

plot2 = Tucan.new(x: x, y: y)

assert plot1 == plot2

For all other tensor shapes an ArgumentError will be raised.

Plots

Link to this function

area(plotdata, x, y, opts \\ [])

View Source
@spec area(plotdata :: plotdata(), x :: field(), y :: field(), opts :: keyword()) ::
  VegaLite.t()

Returns the specification of an area plot.

Options

  • :interpolate (binary/0) - The line interpolation method to use for line and area marks. One of the following:
    • "linear" - piecewise linear segments, as in a poly-line.
    • "linear-closed" - close the linear segments to form a polygon.
    • "step" - alternate between horizontal and vertical segments, as in a step function.
    • "step-before" - alternate between vertical and horizontal segments, as in a step function.
    • "step-after" - alternate between horizontal and vertical segments, as in a step function.
    • "basis" - a B-spline, with control point duplication on the ends.
    • "basis-open" - an open B-spline; may not intersect the start or end.
    • "basis-closed" - a closed B-spline, as in a loop.
    • "cardinal" - a Cardinal spline, with control point duplication on the ends.
    • "cardinal-open" - an open Cardinal spline; may not intersect the start or end, but will intersect other control points.
    • "cardinal-closed" - a closed Cardinal spline, as in a loop.
    • "bundle" - equivalent to basis, except the tension parameter is used to straighten the spline.
    • "monotone" - cubic interpolation that preserves monotonicity in y.
  • :line (boolean/0) - Whether the line will be included in the chart The default value is false.
  • :mode - The stacking mode, applied only if :color_by is set. Can be one of the following:
    • :stacked - the default one, areas are stacked
    • :normalize - the stacked charts are normalized
    • :streamgraph - the chart is displaced around a central axis
    • :no_stack - no stacking is applied The default value is :stacked.
  • :points (boolean/0) - Whether points will be included in the chart. The default value is false.
  • :tension (number/0) - Depending on the interpolation type, sets the tension parameter

Data Grouping Options

  • :color_by (String.t/0) - If set a data field that will be used for coloring the data. It is considered :nominal by default.

Data Options

  • :only - A subset of fields to pick from the data. Applicable only if tabular data are provided.

Styling Options

  • :clip (boolean/0) - Whether a mark will be clipped to the enclosing group’s width and height.
  • :fill_color (String.t/0) - The fill color of the marks. This will override the color encoding if set.
  • :fill_opacity (number/0) - The fill opacity of the plotted elements. The default value is 1.
  • :height (pos_integer/0 or :container) - Height of the plot. Can either be the height in pixels or :container to indicate that the height of the plot should be the same as its surrounding container.
  • :line_color (String.t/0) - The color of the line
  • :point_color (String.t/0) - The color of the points
  • :title (String.t/0) - The title of the graph
  • :width (pos_integer/0 or :container) - Width of the plot. Can either be the width in pixels or :container to indicate that the width of the plot should be the same as its surrounding container.

Encodings Custom Options

All Tucan plots are building a VegaLite specification based on some sane default parameters. Through these encodings options you are free to set any vega-lite supported option to any encoding channel of the plot.

Notice that if set they will be merged with any option set by the plot. Since they have a higher precedence they may override the default settings and affect the generated plot.

You can set an arbitrary keyword list. Notice that the contents are not validated.

  • :color (keyword/0) - Extra vega lite options for the :color encoding. The default value is [].
  • :x (keyword/0) - Extra vega lite options for the :x encoding. The default value is [].
  • :y (keyword/0) - Extra vega lite options for the :y encoding. The default value is [].

Interactivity Options

  • :tooltip (boolean() | :data | :encoding) - The tooltip text string to show upon mouse hover or an object defining which fields should the tooltip be derived from. Can be one of the following:

    • :encoding - all fields from encoding are used
    • :data - all fields of the highlighted data point are used
    • true - same as :encoding
    • false, nil - no tooltip is used
  • :zoomable (boolean/0) - Whether the plot will be zoomable or not. If set to true you will be able to pan and zoom the plot with your mouse. You can reset to the original view with a double click. The default value is false.

Examples

A simple area chart of Google stock price over time. Notice how we change the x axis type from the default (:quantitative) to :temporal using the generic :x channel configuration option:

Tucan.area(:stocks, "date", "price", x: [type: :temporal])
|> VegaLite.transform(filter: "datum.symbol==='GOOG'")
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://vega.github.io/editor/data/stocks.csv"},"encoding":{"x":{"field":"date","type":"temporal"},"y":{"field":"price","stack":true,"type":"quantitative"}},"mark":{"fillOpacity":1,"line":false,"type":"area"},"transform":[{"filter":"datum.symbol==='GOOG'"}]}

You can overlay the points and/or the line, you can change the colors of the points, the line and the area if needed:

Tucan.area(:stocks, "date", "price",
  x: [type: :temporal],
  points: true,
  line: true,
  fill_color: "#fa3456",
  point_color: "orange",
  line_color: "green",
  width: 400
)
|> VegaLite.transform(filter: "datum.symbol==='GOOG'")
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://vega.github.io/editor/data/stocks.csv"},"encoding":{"x":{"field":"date","type":"temporal"},"y":{"field":"price","stack":true,"type":"quantitative"}},"mark":{"color":"#fa3456","fillOpacity":1,"line":{"color":"green"},"point":{"color":"orange"},"type":"area"},"transform":[{"filter":"datum.symbol==='GOOG'"}],"width":400}

If you add the :color_by property then the area charts are stacked by default. Below you can see how the generic encoding options can be used in order to modify any part of the underlying VegaLite specification:

Tucan.area(:unemployment, "date", "count",
  color_by: "series",
  x: [type: :temporal, time_unit: :yearmonth, axis: [format: "%Y"]],
  y: [aggregate: :sum],
  color: [scale: [scheme: "category20b"]],
  width: 300,
  height: 200
)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://vega.github.io/editor/data/unemployment-across-industries.json"},"encoding":{"color":{"field":"series","scale":{"scheme":"category20b"}},"x":{"axis":{"format":"%Y"},"field":"date","timeUnit":"yearmonth","type":"temporal"},"y":{"aggregate":"sum","field":"count","stack":true,"type":"quantitative"}},"height":200,"mark":{"fillOpacity":1,"line":false,"type":"area"},"width":300}

You could change the mode to :normalize or :streamgraph:

left =
  Tucan.area(:unemployment, "date", "count",
    color_by: "series",
    mode: :normalize,
    x: [type: :temporal, time_unit: :yearmonth, axis: [format: "%Y"]],
    y: [aggregate: :sum]
  )
  |> Tucan.set_title("normalize")

right =
  Tucan.area(:unemployment, "date", "count",
    color_by: "series",
    mode: :streamgraph,
    x: [type: :temporal, time_unit: :yearmonth, axis: [format: "%Y"]],
    y: [aggregate: :sum]
  )
  |> Tucan.set_title("streamgraph")

Tucan.hconcat([left, right])
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","hconcat":[{"data":{"url":"https://vega.github.io/editor/data/unemployment-across-industries.json"},"encoding":{"color":{"field":"series"},"x":{"axis":{"format":"%Y"},"field":"date","timeUnit":"yearmonth","type":"temporal"},"y":{"aggregate":"sum","field":"count","stack":"normalize","type":"quantitative"}},"mark":{"fillOpacity":1,"line":false,"type":"area"},"title":{"text":"normalize"}},{"data":{"url":"https://vega.github.io/editor/data/unemployment-across-industries.json"},"encoding":{"color":{"field":"series"},"x":{"axis":{"format":"%Y"},"field":"date","timeUnit":"yearmonth","type":"temporal"},"y":{"aggregate":"sum","field":"count","stack":"center","type":"quantitative"}},"mark":{"fillOpacity":1,"line":false,"type":"area"},"title":{"text":"streamgraph"}}]}

Or you could disable the stacking at all:

Tucan.area(:stocks, "date", "price",
  color_by: "symbol",
  mode: :no_stack,
  x: [type: :temporal],
  width: 400,
  fill_opacity: 0.4
)
|> Tucan.Scale.set_y_scale(:log)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://vega.github.io/editor/data/stocks.csv"},"encoding":{"color":{"field":"symbol"},"x":{"field":"date","type":"temporal"},"y":{"field":"price","scale":{"type":"log"},"stack":false,"type":"quantitative"}},"mark":{"fillOpacity":0.4,"line":false,"type":"area"},"width":400}
Link to this function

bar(plotdata, field, value, opts \\ [])

View Source
@spec bar(
  plotdata :: plotdata(),
  field :: String.t(),
  value :: String.t(),
  opts :: keyword()
) ::
  VegaLite.t()

Draws a bar chart.

A bar chart is consisted by a categorical field and a numerical value field that defines the height of the bars. You can create a grouped bar chart by setting the :color_by option.

Additionally you should specify the aggregate for the y values, if your dataset contains more than one values per category.

See also lollipop/4.

Options

  • :mode - The stacking mode, applied only if :color_by is set. Can be one of the following:
    • :stacked - the default one, bars are stacked
    • :normalize - the bars are stacked are normalized
    • :grouped - no stacking is applied, a separate bar for each category The default value is :stacked.

Data Grouping Options

  • :color_by (String.t/0) - If set a data field that will be used for coloring the data. It is considered :nominal by default.

Data Options

  • :only - A subset of fields to pick from the data. Applicable only if tabular data are provided.

Styling Options

  • :clip (boolean/0) - Whether a mark will be clipped to the enclosing group’s width and height.
  • :corner_radius (non_neg_integer/0) - The radius in pixels of rounded rectangles. The end radius is affected:
    • For vertical bars, top-left and top-right corner radius.
    • For horizontal bars, top-right and bottom-right corner radius.
  • :fill_color (String.t/0) - The fill color of the marks. This will override the color encoding if set.
  • :fill_opacity (number/0) - The fill opacity of the plotted elements. The default value is 1.
  • :height (pos_integer/0 or :container) - Height of the plot. Can either be the height in pixels or :container to indicate that the height of the plot should be the same as its surrounding container.
  • :orient (atom/0) - The plot's orientation, can be either :horizontal or :vertical. The default value is :vertical.
  • :title (String.t/0) - The title of the graph
  • :width (pos_integer/0 or :container) - Width of the plot. Can either be the width in pixels or :container to indicate that the width of the plot should be the same as its surrounding container.

Encodings Custom Options

All Tucan plots are building a VegaLite specification based on some sane default parameters. Through these encodings options you are free to set any vega-lite supported option to any encoding channel of the plot.

Notice that if set they will be merged with any option set by the plot. Since they have a higher precedence they may override the default settings and affect the generated plot.

You can set an arbitrary keyword list. Notice that the contents are not validated.

  • :color (keyword/0) - Extra vega lite options for the :color encoding. The default value is [].
  • :x (keyword/0) - Extra vega lite options for the :x encoding. The default value is [].
  • :x_offset (keyword/0) - Extra vega lite options for the :x_offset encoding. The default value is [].
  • :y (keyword/0) - Extra vega lite options for the :y encoding. The default value is [].
  • :y_offset (keyword/0) - Extra vega lite options for the :y_offset encoding. The default value is [].

Interactivity Options

  • :tooltip (boolean() | :data | :encoding) - The tooltip text string to show upon mouse hover or an object defining which fields should the tooltip be derived from. Can be one of the following:

    • :encoding - all fields from encoding are used
    • :data - all fields of the highlighted data point are used
    • true - same as :encoding
    • false, nil - no tooltip is used

Examples

A simple bar chart:

data = [
  %{"a" => "A", "b" => 28},
  %{"a" => "B", "b" => 55},
  %{"a" => "C", "b" => 43},
  %{"a" => "D", "b" => 91},
  %{"a" => "E", "b" => 81},
  %{"a" => "F", "b" => 53},
  %{"a" => "G", "b" => 19},
  %{"a" => "H", "b" => 87},
  %{"a" => "I", "b" => 52}
]

Tucan.bar(data, "a", "b", fill_color: "#33245A", corner_radius: 5)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"values":[{"a":"A","b":28},{"a":"B","b":55},{"a":"C","b":43},{"a":"D","b":91},{"a":"E","b":81},{"a":"F","b":53},{"a":"G","b":19},{"a":"H","b":87},{"a":"I","b":52}]},"encoding":{"x":{"axis":{"labelAngle":0},"field":"a","type":"nominal"},"y":{"field":"b","type":"quantitative"}},"mark":{"color":"#33245A","cornerRadiusEnd":5,"fillOpacity":1,"type":"bar"}}

You can set a color_by option that will create a stacked bar chart:

Tucan.bar(:weather, "date", "date",
  color_by: "weather",
  tooltip: true,
  x: [type: :ordinal, time_unit: :month],
  y: [aggregate: :count]
)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://vega.github.io/editor/data/weather.csv"},"encoding":{"color":{"field":"weather"},"x":{"axis":{"labelAngle":0},"field":"date","timeUnit":"month","type":"ordinal"},"y":{"aggregate":"count","field":"date","type":"quantitative"}},"mark":{"fillOpacity":1,"tooltip":true,"type":"bar"}}

If you set the mode option to :grouped you will instead have a different bar per group, you can also change the orientation by setting the :orient flag. Similarly you can set the mode to :normalize in order to have normalized stacked bars.

data = [
  %{"category" => "A", "group" => "x", "value" => 0.1},
  %{"category" => "A", "group" => "y", "value" => 0.6},
  %{"category" => "A", "group" => "z", "value" => 0.9},
  %{"category" => "B", "group" => "x", "value" => 0.7},
  %{"category" => "B", "group" => "y", "value" => 0.2},
  %{"category" => "B", "group" => "z", "value" => 1.1},
  %{"category" => "C", "group" => "x", "value" => 0.6},
  %{"category" => "C", "group" => "y", "value" => 0.1},
  %{"category" => "C", "group" => "z", "value" => 0.2}
]

grouped =
  Tucan.bar(
    data,
    "category",
    "value",
    color_by: "group",
    mode: :grouped,
    orient: :horizontal
  )

normalized =
  Tucan.bar(
    data,
    "category",
    "value",
    color_by: "group",
    mode: :normalize
  )

Tucan.hconcat([grouped, normalized])
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","hconcat":[{"data":{"values":[{"category":"A","group":"x","value":0.1},{"category":"A","group":"y","value":0.6},{"category":"A","group":"z","value":0.9},{"category":"B","group":"x","value":0.7},{"category":"B","group":"y","value":0.2},{"category":"B","group":"z","value":1.1},{"category":"C","group":"x","value":0.6},{"category":"C","group":"y","value":0.1},{"category":"C","group":"z","value":0.2}]},"encoding":{"color":{"field":"group"},"x":{"field":"value","type":"quantitative"},"y":{"axis":{"labelAngle":0},"field":"category","type":"nominal"},"yOffset":{"field":"group"}},"mark":{"fillOpacity":1,"type":"bar"}},{"data":{"values":[{"category":"A","group":"x","value":0.1},{"category":"A","group":"y","value":0.6},{"category":"A","group":"z","value":0.9},{"category":"B","group":"x","value":0.7},{"category":"B","group":"y","value":0.2},{"category":"B","group":"z","value":1.1},{"category":"C","group":"x","value":0.6},{"category":"C","group":"y","value":0.1},{"category":"C","group":"z","value":0.2}]},"encoding":{"color":{"field":"group"},"x":{"axis":{"labelAngle":0},"field":"category","type":"nominal"},"y":{"field":"value","stack":"normalize","type":"quantitative"}},"mark":{"fillOpacity":1,"type":"bar"}}]}
Link to this function

boxplot(plotdata, field, opts \\ [])

View Source
@spec boxplot(plotdata :: plotdata(), field :: String.t(), opts :: keyword()) ::
  VegaLite.t()

Returns the specification of a box plot.

By default a one dimensional box plot of the :field - which must be a numerical variable - is generated. You can add a second dimension across a categorical variable by either setting the :group_by or :color_by options.

By default a Tukey box plot will be generated. In the Tukey box plot the whisker spans from the smallest data to the largest data within the range [Q1 - k * IQR, Q3 + k * IQR] where Q1and Q3 are the first and third quartiles while IQR is the interquartile range (Q3-Q1). You can specify if needed the constant k which defaults to 1.5.

Additionally you can set the mode to :min_max where the lower and upper whiskers are defined as the min and max respectively. No points will be considered as outliers for this type of box plots. In this case the k value is ignored.

What is a box plot

A box plot (box and whisker plot) displays the five-number summary of a set of data. The five-number summary is the minimum, first quartile, median, third quartile, and maximum. In a box plot, we draw a box from the first quartile to the third quartile. A vertical line goes through the box at the median.

Options

  • :k (float/0) - The constant used for calculating the extent of the whiskers in a Tukey boxplot. Applicable only if :mode is set to :tukey. The default value is 1.5.
  • :mode - The type of the box plot. Either a Tukey box plot (:tukey) or a min-max plot (:min_max) will be created. The default value is :tukey.

Data Grouping Options

  • :color_by (String.t/0) - If set a data field that will be used for coloring the data. It is considered :nominal by default.
  • :group_by (String.t/0) - A field to be used for grouping the boxplot. It is used for adding a second dimension to the plot. If not set the plot will be one dimensional. Notice that a grouping is automatically applied if the :color_by option is set.

Data Options

  • :only - A subset of fields to pick from the data. Applicable only if tabular data are provided.

Styling Options

  • :clip (boolean/0) - Whether a mark will be clipped to the enclosing group’s width and height.
  • :fill_opacity (number/0) - The fill opacity of the plotted elements. The default value is 1.
  • :height (pos_integer/0 or :container) - Height of the plot. Can either be the height in pixels or :container to indicate that the height of the plot should be the same as its surrounding container.
  • :orient (atom/0) - The plot's orientation, can be either :horizontal or :vertical. The default value is :horizontal.
  • :title (String.t/0) - The title of the graph
  • :width (pos_integer/0 or :container) - Width of the plot. Can either be the width in pixels or :container to indicate that the width of the plot should be the same as its surrounding container.

Encodings Custom Options

All Tucan plots are building a VegaLite specification based on some sane default parameters. Through these encodings options you are free to set any vega-lite supported option to any encoding channel of the plot.

Notice that if set they will be merged with any option set by the plot. Since they have a higher precedence they may override the default settings and affect the generated plot.

You can set an arbitrary keyword list. Notice that the contents are not validated.

  • :color (keyword/0) - Extra vega lite options for the :color encoding. The default value is [].
  • :x (keyword/0) - Extra vega lite options for the :x encoding. The default value is [].
  • :y (keyword/0) - Extra vega lite options for the :y encoding. The default value is [].

Interactivity Options

  • :tooltip (boolean() | :data | :encoding) - The tooltip text string to show upon mouse hover or an object defining which fields should the tooltip be derived from. Can be one of the following:

    • :encoding - all fields from encoding are used
    • :data - all fields of the highlighted data point are used
    • true - same as :encoding
    • false, nil - no tooltip is used

Examples

A one dimensional Tukey boxplot:

Tucan.boxplot(:penguins, "Body Mass (g)")
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://raw.githubusercontent.com/vega/vega-datasets/next/data/penguins.json"},"encoding":{"x":{"field":"Body Mass (g)","scale":{"zero":false},"type":"quantitative"}},"mark":{"extent":1.5,"fillOpacity":1,"type":"boxplot"}}

You can set :group_by or :color_by in order to set a second dimension:

Tucan.boxplot(:penguins, "Body Mass (g)", color_by: "Species")
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://raw.githubusercontent.com/vega/vega-datasets/next/data/penguins.json"},"encoding":{"color":{"field":"Species"},"x":{"field":"Body Mass (g)","scale":{"zero":false},"type":"quantitative"},"y":{"field":"Species","type":"nominal"}},"mark":{"extent":1.5,"fillOpacity":1,"type":"boxplot"}}

You can set the mode to :min_max in order to extend the whiskers to the min and max values:

Tucan.boxplot(:penguins, "Body Mass (g)", color_by: "Species", mode: :min_max)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://raw.githubusercontent.com/vega/vega-datasets/next/data/penguins.json"},"encoding":{"color":{"field":"Species"},"x":{"field":"Body Mass (g)","scale":{"zero":false},"type":"quantitative"},"y":{"field":"Species","type":"nominal"}},"mark":{"extent":"min-max","fillOpacity":1,"type":"boxplot"}}

By setting the :orient to :vertical you can change the default horizontal orientation:

Tucan.boxplot(:penguins, "Body Mass (g)", color_by: "Species", orient: :vertical)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://raw.githubusercontent.com/vega/vega-datasets/next/data/penguins.json"},"encoding":{"color":{"field":"Species"},"x":{"field":"Species","type":"nominal"},"y":{"field":"Body Mass (g)","scale":{"zero":false},"type":"quantitative"}},"mark":{"extent":1.5,"fillOpacity":1,"type":"boxplot"}}
Link to this function

bubble(plotdata, x, y, size, opts \\ [])

View Source
@spec bubble(
  plotdata :: plotdata(),
  x :: field(),
  y :: field(),
  size :: field(),
  opts :: keyword()
) :: VegaLite.t()

Returns the specification of a bubble plot.

A bubble plot is a scatter plot with a third parameter defining the size of the dots.

All x, y and size must be numerical data fields.

See also scatter/4.

Options

Data Grouping Options

  • :color_by (String.t/0) - If set a data field that will be used for coloring the data. It is considered :nominal by default.

Data Options

  • :only - A subset of fields to pick from the data. Applicable only if tabular data are provided.

Styling Options

  • :clip (boolean/0) - Whether a mark will be clipped to the enclosing group’s width and height.
  • :fill_opacity (number/0) - The fill opacity of the plotted elements. The default value is 1.
  • :height (pos_integer/0 or :container) - Height of the plot. Can either be the height in pixels or :container to indicate that the height of the plot should be the same as its surrounding container.
  • :title (String.t/0) - The title of the graph
  • :width (pos_integer/0 or :container) - Width of the plot. Can either be the width in pixels or :container to indicate that the width of the plot should be the same as its surrounding container.

Encodings Custom Options

All Tucan plots are building a VegaLite specification based on some sane default parameters. Through these encodings options you are free to set any vega-lite supported option to any encoding channel of the plot.

Notice that if set they will be merged with any option set by the plot. Since they have a higher precedence they may override the default settings and affect the generated plot.

You can set an arbitrary keyword list. Notice that the contents are not validated.

  • :color (keyword/0) - Extra vega lite options for the :color encoding. The default value is [].
  • :size (keyword/0) - Extra vega lite options for the :size encoding. The default value is [].
  • :x (keyword/0) - Extra vega lite options for the :x encoding. The default value is [].
  • :y (keyword/0) - Extra vega lite options for the :y encoding. The default value is [].

Interactivity Options

  • :tooltip (boolean() | :data | :encoding) - The tooltip text string to show upon mouse hover or an object defining which fields should the tooltip be derived from. Can be one of the following:

    • :encoding - all fields from encoding are used
    • :data - all fields of the highlighted data point are used
    • true - same as :encoding
    • false, nil - no tooltip is used
  • :zoomable (boolean/0) - Whether the plot will be zoomable or not. If set to true you will be able to pan and zoom the plot with your mouse. You can reset to the original view with a double click. The default value is false.

Examples

Tucan.bubble(:gapminder, "income", "health", "population", width: 400)
|> Tucan.Axes.set_x_title("Gdp per Capita")
|> Tucan.Axes.set_y_title("Life expectancy")
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://vega.github.io/vega-datasets/data/gapminder-health-income.csv"},"encoding":{"size":{"field":"population","type":"quantitative"},"x":{"axis":{"title":"Gdp per Capita"},"field":"income","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":"Life expectancy"},"field":"health","scale":{"zero":false},"type":"quantitative"}},"mark":"circle","width":400}

You could use a fourth variable to color the graph. As always you can set the tooltip in order to make the plot interactive:

Tucan.bubble(:gapminder, "income", "health", "population",
  color_by: "region",
  width: 400,
  tooltip: :data
)
|> Tucan.Axes.set_x_title("Gdp per Capita")
|> Tucan.Axes.set_y_title("Life expectancy")
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://vega.github.io/vega-datasets/data/gapminder-health-income.csv"},"encoding":{"color":{"field":"region","type":"nominal"},"size":{"field":"population","type":"quantitative"},"x":{"axis":{"title":"Gdp per Capita"},"field":"income","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":"Life expectancy"},"field":"health","scale":{"zero":false},"type":"quantitative"}},"mark":{"tooltip":{"content":"data"},"type":"circle"},"width":400}

It makes more sense to use a log scale for the x axis:

Tucan.bubble(:gapminder, "income", "health", "population",
  color_by: "region",
  width: 400,
  tooltip: :data
)
|> Tucan.Axes.set_x_title("Gdp per Capita")
|> Tucan.Axes.set_y_title("Life expectancy")
|> Tucan.Scale.set_x_scale(:log)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://vega.github.io/vega-datasets/data/gapminder-health-income.csv"},"encoding":{"color":{"field":"region","type":"nominal"},"size":{"field":"population","type":"quantitative"},"x":{"axis":{"title":"Gdp per Capita"},"field":"income","scale":{"type":"log","zero":false},"type":"quantitative"},"y":{"axis":{"title":"Life expectancy"},"field":"health","scale":{"zero":false},"type":"quantitative"}},"mark":{"tooltip":{"content":"data"},"type":"circle"},"width":400}
Link to this function

countplot(plotdata, field, opts \\ [])

View Source
@spec countplot(plotdata :: plotdata(), field :: String.t(), opts :: keyword()) ::
  VegaLite.t()

Plot the counts of observations for a categorical variable.

Takes a categorical field as input and generates a count plot visualization. By default the counts are plotted on the y-axis and the categorical field across the x-axis.

This is similar to histogram/3 but specifically for a categorical variable.

This is a simple wrapper around bar/4 where by default the count of observations is mapped to the y variable.

What is a countplot?

A countplot is a type of bar chart used in data visualization to display the frequency of occurrences of categorical data. It is particularly useful for visualizing the distribution and frequency of different categories within a dataset.

In a countplot, each unique category is represented by a bar, and the height of the bar corresponds to the number of occurrences of that category in the data.

Options

See bar/4

Examples

We will use the :titanic dataset on the following examples. We can plot the number of passengers by ticket class:

Tucan.countplot(:titanic, "Pclass")
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv"},"encoding":{"x":{"axis":{"labelAngle":0},"field":"Pclass","type":"nominal"},"y":{"aggregate":"count","field":"Pclass","type":"quantitative"}},"mark":{"fillOpacity":1,"type":"bar"}}

You can make the bars horizontal by setting the :orient option:

Tucan.countplot(:titanic, "Pclass", orient: :horizontal)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv"},"encoding":{"x":{"aggregate":"count","field":"Pclass","type":"quantitative"},"y":{"axis":{"labelAngle":0},"field":"Pclass","type":"nominal"}},"mark":{"fillOpacity":1,"type":"bar"}}

You can set :color_by to group it by a second variable:

Tucan.countplot(:titanic, "Pclass", color_by: "Survived")
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv"},"encoding":{"color":{"field":"Survived"},"x":{"axis":{"labelAngle":0},"field":"Pclass","type":"nominal"},"y":{"aggregate":"count","field":"Pclass","type":"quantitative"}},"mark":{"fillOpacity":1,"type":"bar"}}

By default the bars are stacked. You can unstack them by setting the :mode to :grouped

Tucan.countplot(:titanic, "Pclass", color_by: "Survived", mode: :grouped)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv"},"encoding":{"color":{"field":"Survived"},"x":{"axis":{"labelAngle":0},"field":"Pclass","type":"nominal"},"xOffset":{"field":"Survived"},"y":{"aggregate":"count","field":"Pclass","type":"quantitative"}},"mark":{"fillOpacity":1,"type":"bar"}}
Link to this function

density(plotdata, field, opts \\ [])

View Source
@spec density(plotdata :: plotdata(), field :: String.t(), opts :: keyword()) ::
  VegaLite.t()

Plot the distribution of a numeric variable.

Density plots allow you to visualize the distribution of a numeric variable for one or several groups. If you want to draw the density for several groups you need to specify the :color_by option which is assumed to be a categorical variable.

Avoid calling color_by/3 with a density plot

Since the grouping variable must also be used for properly calculating the density transformation you should avoid calling the color_by/3 grouping function after a density/3 call. Instead use the :color_by option, which will ensure that the proper settings are applied to the underlying transformation.

Calling color_by/3 would produce this graph:

Tucan.density(:penguins, "Body Mass (g)")
|> Tucan.color_by("Species")
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://raw.githubusercontent.com/vega/vega-datasets/next/data/penguins.json"},"encoding":{"color":{"field":"Species"},"x":{"axis":{"title":"Body Mass (g)"},"field":"value","scale":{"zero":false},"type":"quantitative"},"y":{"field":"density","stack":null,"type":"quantitative"}},"mark":{"fillOpacity":1,"orient":"vertical","type":"area"},"transform":[{"counts":false,"cumulative":false,"density":"Body Mass (g)","maxsteps":200,"minsteps":25}]}

In the above case the density function has been calculated on the complete dataset and you cannot color by the Species. Instead you should use the :color_by option which would calculate the density function per group:

Tucan.density(:penguins, "Body Mass (g)", color_by: "Species", fill_opacity: 0.2)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://raw.githubusercontent.com/vega/vega-datasets/next/data/penguins.json"},"encoding":{"color":{"field":"Species"},"x":{"axis":{"title":"Body Mass (g)"},"field":"value","scale":{"zero":false},"type":"quantitative"},"y":{"field":"density","stack":null,"type":"quantitative"}},"mark":{"fillOpacity":0.2,"orient":"vertical","type":"area"},"transform":[{"counts":false,"cumulative":false,"density":"Body Mass (g)","groupby":["Species"],"maxsteps":200,"minsteps":25}]}

Alternatively you should use the :group_by option in order to group the density transform by the Species field and then apply the color_by/3 function:

Tucan.density(:penguins, "Body Mass (g)", group_by: ["Species"], fill_opacity: 0.2)
|> Tucan.color_by("Species")

See also histogram/3.

Options

  • :bandwidth (float/0) - The bandwidth (standard deviation) of the Gaussian kernel. If unspecified or set to zero, the bandwidth value is automatically estimated from the input data using Scott’s rule.

  • :counts (boolean/0) - A boolean flag indicating if the output values should be probability estimates (false) or smoothed counts (true). The default value is false.

  • :cumulative (boolean/0) - A boolean flag indicating whether to produce density estimates (false) or cumulative density estimates (true). The default value is false.

  • :extent - A [min, max] domain from which to sample the distribution. If unspecified, the extent will be determined by the observed minimum and maximum values of the density value field.

  • :group_by (list of String.t/0) - The data fields to group by. If not specified, a single group containing all data objects will be used. This is applied only on the density transform.

    In most cases you only need to set :color_by which will automatically handle the density transform grouping. Use :group_by only if you want to manually post-process the generated specification, or if you want to apply grouping by more than one variable.

    If both :group_by and :color_by are set then only :group_by is used for grouping the density transform and color_by is used for encoding the color.

  • :interpolate (binary/0) - The line interpolation method to use for line and area marks. One of the following:

    • "linear" - piecewise linear segments, as in a poly-line.
    • "linear-closed" - close the linear segments to form a polygon.
    • "step" - alternate between horizontal and vertical segments, as in a step function.
    • "step-before" - alternate between vertical and horizontal segments, as in a step function.
    • "step-after" - alternate between horizontal and vertical segments, as in a step function.
    • "basis" - a B-spline, with control point duplication on the ends.
    • "basis-open" - an open B-spline; may not intersect the start or end.
    • "basis-closed" - a closed B-spline, as in a loop.
    • "cardinal" - a Cardinal spline, with control point duplication on the ends.
    • "cardinal-open" - an open Cardinal spline; may not intersect the start or end, but will intersect other control points.
    • "cardinal-closed" - a closed Cardinal spline, as in a loop.
    • "bundle" - equivalent to basis, except the tension parameter is used to straighten the spline.
    • "monotone" - cubic interpolation that preserves monotonicity in y.
  • :maxsteps (integer/0) - The maximum number of samples to take along the extent domain for plotting the density. The default value is 200.

  • :minsteps (integer/0) - The minimum number of samples to take along the extent domain for plotting the density. The default value is 25.

  • :stacked (boolean/0) - Whether the density plots will be stacked or not. The default value is false.

  • :steps (integer/0) - The exact number of samples to take along the extent domain for plotting the density. If specified, overrides both minsteps and maxsteps to set an exact number of uniform samples. Potentially useful in conjunction with a fixed extent to ensure consistent sample points for stacked densities.

Data Grouping Options

  • :color_by (String.t/0) - If set a data field that will be used for coloring the data. It is considered :nominal by default.

Data Options

  • :only - A subset of fields to pick from the data. Applicable only if tabular data are provided.

Styling Options

  • :clip (boolean/0) - Whether a mark will be clipped to the enclosing group’s width and height.
  • :fill_color (String.t/0) - The fill color of the marks. This will override the color encoding if set.
  • :fill_opacity (number/0) - The fill opacity of the plotted elements. The default value is 1.
  • :filled (boolean/0) - Whether the density plot will be filled or not, default to true if not set
  • :height (pos_integer/0 or :container) - Height of the plot. Can either be the height in pixels or :container to indicate that the height of the plot should be the same as its surrounding container.
  • :orient (atom/0) - The plot's orientation, can be either :horizontal or :vertical. The default value is :horizontal.
  • :title (String.t/0) - The title of the graph
  • :width (pos_integer/0 or :container) - Width of the plot. Can either be the width in pixels or :container to indicate that the width of the plot should be the same as its surrounding container.

Encodings Custom Options

All Tucan plots are building a VegaLite specification based on some sane default parameters. Through these encodings options you are free to set any vega-lite supported option to any encoding channel of the plot.

Notice that if set they will be merged with any option set by the plot. Since they have a higher precedence they may override the default settings and affect the generated plot.

You can set an arbitrary keyword list. Notice that the contents are not validated.

  • :color (keyword/0) - Extra vega lite options for the :color encoding. The default value is [].
  • :x (keyword/0) - Extra vega lite options for the :x encoding. The default value is [].
  • :y (keyword/0) - Extra vega lite options for the :y encoding. The default value is [].

Interactivity Options

  • :tooltip (boolean() | :data | :encoding) - The tooltip text string to show upon mouse hover or an object defining which fields should the tooltip be derived from. Can be one of the following:

    • :encoding - all fields from encoding are used
    • :data - all fields of the highlighted data point are used
    • true - same as :encoding
    • false, nil - no tooltip is used
  • :zoomable (boolean/0) - Whether the plot will be zoomable or not. If set to true you will be able to pan and zoom the plot with your mouse. You can reset to the original view with a double click. The default value is false.

Examples

Tucan.density(:penguins, "Body Mass (g)")
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://raw.githubusercontent.com/vega/vega-datasets/next/data/penguins.json"},"encoding":{"x":{"axis":{"title":"Body Mass (g)"},"field":"value","scale":{"zero":false},"type":"quantitative"},"y":{"field":"density","stack":null,"type":"quantitative"}},"mark":{"fillOpacity":1,"orient":"vertical","type":"area"},"transform":[{"counts":false,"cumulative":false,"density":"Body Mass (g)","maxsteps":200,"minsteps":25}]}

It is a common use case to compare the density of several groups in a dataset. Several options exist to do so. You can plot all items on the same chart, using transparency and annotation to make the comparison possible. You can stack overlapping densities by setting the :stacked property.

unstacked =
  Tucan.density(:penguins, "Body Mass (g)", color_by: "Species", fill_opacity: 0.2)
  |> Tucan.set_title("Unstacked")

stacked =
  Tucan.density(:penguins, "Body Mass (g)",
    color_by: "Species",
    fill_opacity: 0.8,
    stacked: true
  )
  |> Tucan.set_title("Stacked")

Tucan.hconcat([unstacked, stacked])
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","hconcat":[{"data":{"url":"https://raw.githubusercontent.com/vega/vega-datasets/next/data/penguins.json"},"encoding":{"color":{"field":"Species"},"x":{"axis":{"title":"Body Mass (g)"},"field":"value","scale":{"zero":false},"type":"quantitative"},"y":{"field":"density","stack":null,"type":"quantitative"}},"mark":{"fillOpacity":0.2,"orient":"vertical","type":"area"},"title":{"text":"Unstacked"},"transform":[{"counts":false,"cumulative":false,"density":"Body Mass (g)","groupby":["Species"],"maxsteps":200,"minsteps":25}]},{"data":{"url":"https://raw.githubusercontent.com/vega/vega-datasets/next/data/penguins.json"},"encoding":{"color":{"field":"Species"},"x":{"axis":{"title":"Body Mass (g)"},"field":"value","scale":{"zero":false},"type":"quantitative"},"y":{"field":"density","stack":"zero","type":"quantitative"}},"mark":{"fillOpacity":0.8,"orient":"vertical","type":"area"},"title":{"text":"Stacked"},"transform":[{"counts":false,"cumulative":false,"density":"Body Mass (g)","groupby":["Species"],"maxsteps":200,"minsteps":25}]}]}

You can also combine it with facet_by/4 in order to draw a different plot for each value of the grouping variable. Notice that we need to set the :group_by variable in order to correctly calculate the density plot per field's value.

Tucan.density(:penguins, "Body Mass (g)", group_by: ["Species"])
|> Tucan.color_by("Species")
|> Tucan.facet_by(:column, "Species")
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://raw.githubusercontent.com/vega/vega-datasets/next/data/penguins.json"},"encoding":{"color":{"field":"Species"},"column":{"field":"Species"},"x":{"axis":{"title":"Body Mass (g)"},"field":"value","scale":{"zero":false},"type":"quantitative"},"y":{"field":"density","stack":null,"type":"quantitative"}},"mark":{"fillOpacity":1,"orient":"vertical","type":"area"},"transform":[{"counts":false,"cumulative":false,"density":"Body Mass (g)","groupby":["Species"],"maxsteps":200,"minsteps":25}]}

You can control the smoothing by setting a specific bandwidth value (if not set it is automatically calculated by vega lite):

Tucan.density(:penguins, "Body Mass (g)",
  color_by: "Species",
  bandwidth: 50.0,
  fill_opacity: 0.5
)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://raw.githubusercontent.com/vega/vega-datasets/next/data/penguins.json"},"encoding":{"color":{"field":"Species"},"x":{"axis":{"title":"Body Mass (g)"},"field":"value","scale":{"zero":false},"type":"quantitative"},"y":{"field":"density","stack":null,"type":"quantitative"}},"mark":{"fillOpacity":0.5,"orient":"vertical","type":"area"},"transform":[{"bandwidth":50.0,"counts":false,"cumulative":false,"density":"Body Mass (g)","groupby":["Species"],"maxsteps":200,"minsteps":25}]}

You can plot a cumulative density distribution by setting the :cumulative option to true:

Tucan.density(:penguins, "Body Mass (g)", cumulative: true)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://raw.githubusercontent.com/vega/vega-datasets/next/data/penguins.json"},"encoding":{"x":{"axis":{"title":"Body Mass (g)"},"field":"value","scale":{"zero":false},"type":"quantitative"},"y":{"field":"density","stack":null,"type":"quantitative"}},"mark":{"fillOpacity":1,"orient":"vertical","type":"area"},"transform":[{"counts":false,"cumulative":true,"density":"Body Mass (g)","maxsteps":200,"minsteps":25}]}

or calculate a separate cumulative distribution for each group:

Tucan.density(:penguins, "Body Mass (g)", cumulative: true, color_by: "Species")
|> Tucan.facet_by(:column, "Species")
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://raw.githubusercontent.com/vega/vega-datasets/next/data/penguins.json"},"encoding":{"color":{"field":"Species"},"column":{"field":"Species"},"x":{"axis":{"title":"Body Mass (g)"},"field":"value","scale":{"zero":false},"type":"quantitative"},"y":{"field":"density","stack":null,"type":"quantitative"}},"mark":{"fillOpacity":1,"orient":"vertical","type":"area"},"transform":[{"counts":false,"cumulative":true,"density":"Body Mass (g)","groupby":["Species"],"maxsteps":200,"minsteps":25}]}

You can change the color of the plot by setting the :fill_color option and/or specify if it will be filled or not:

Tucan.hconcat([
  Tucan.density(:penguins, "Body Mass (g)", fill_color: "red"),
  Tucan.density(:penguins, "Body Mass (g)", filled: false)
])
|> Tucan.set_theme(:ggplot2)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","config":{"arc":{"fill":"#000"},"area":{"fill":"#000"},"axis":{"domain":false,"grid":true,"gridColor":"#FFFFFF","gridOpacity":1,"labelColor":"#7F7F7F","labelPadding":4,"tickColor":"#7F7F7F","tickSize":5.67,"titleFontSize":16,"titleFontWeight":"normal"},"group":{"fill":"#e5e5e5"},"legend":{"labelBaseline":"middle","labelFontSize":11,"symbolSize":40},"line":{"stroke":"#000"},"path":{"stroke":"#000"},"range":{"category":["#000000","#7F7F7F","#1A1A1A","#999999","#333333","#B0B0B0","#4D4D4D","#C9C9C9","#666666","#DCDCDC"]},"rect":{"fill":"#000"},"shape":{"stroke":"#000"},"symbol":{"fill":"#000","size":40}},"hconcat":[{"data":{"url":"https://raw.githubusercontent.com/vega/vega-datasets/next/data/penguins.json"},"encoding":{"x":{"axis":{"title":"Body Mass (g)"},"field":"value","scale":{"zero":false},"type":"quantitative"},"y":{"field":"density","stack":null,"type":"quantitative"}},"mark":{"color":"red","fillOpacity":1,"orient":"vertical","type":"area"},"transform":[{"counts":false,"cumulative":false,"density":"Body Mass (g)","maxsteps":200,"minsteps":25}]},{"data":{"url":"https://raw.githubusercontent.com/vega/vega-datasets/next/data/penguins.json"},"encoding":{"x":{"axis":{"title":"Body Mass (g)"},"field":"value","scale":{"zero":false},"type":"quantitative"},"y":{"field":"density","stack":null,"type":"quantitative"}},"mark":{"fillOpacity":0,"filled":false,"orient":"vertical","type":"line"},"transform":[{"counts":false,"cumulative":false,"density":"Body Mass (g)","maxsteps":200,"minsteps":25}]}]}
Link to this function

density_heatmap(plotdata, x, y, opts \\ [])

View Source
@spec density_heatmap(
  plotdata :: plotdata(),
  x :: String.t(),
  y :: String.t(),
  opts :: keyword()
) :: VegaLite.t()

Draws a density heatmap.

A density heatmap is a bivariate histogram, e.g. the x, y data are binned within rectangles that tile the plot and then the count of observations within each rectangle is shown with the fill color.

By default the count of observations within each rectangle is encoded, but you can calculate the statistic of any field and use it instead.

Density heatmaps are a powerful visualization tool that find their best use cases in situations where you need to explore and understand the distribution and concentration of data points in a two-dimensional space. They are particularly effective when dealing with large datasets, allowing you to uncover patterns, clusters, and trends that might be difficult to discern in raw data.

Options

  • :aggregate (atom/0) - The statistic that will be used for aggregating the observations within a bin. The z field must be set if aggregate is set.
  • :z (String.t/0) - If set corresponds to the field that will be used for calculating the color fo the bin using the provided aggregate. If not set (the default behaviour) the count of observations are used for coloring the bin.

Data Options

  • :only - A subset of fields to pick from the data. Applicable only if tabular data are provided.

Styling Options

  • :clip (boolean/0) - Whether a mark will be clipped to the enclosing group’s width and height.
  • :fill_opacity (number/0) - The fill opacity of the plotted elements. The default value is 1.
  • :height (pos_integer/0 or :container) - Height of the plot. Can either be the height in pixels or :container to indicate that the height of the plot should be the same as its surrounding container.
  • :title (String.t/0) - The title of the graph
  • :width (pos_integer/0 or :container) - Width of the plot. Can either be the width in pixels or :container to indicate that the width of the plot should be the same as its surrounding container.

Encodings Custom Options

All Tucan plots are building a VegaLite specification based on some sane default parameters. Through these encodings options you are free to set any vega-lite supported option to any encoding channel of the plot.

Notice that if set they will be merged with any option set by the plot. Since they have a higher precedence they may override the default settings and affect the generated plot.

You can set an arbitrary keyword list. Notice that the contents are not validated.

  • :color (keyword/0) - Extra vega lite options for the :color encoding. The default value is [].
  • :x (keyword/0) - Extra vega lite options for the :x encoding. The default value is [].
  • :y (keyword/0) - Extra vega lite options for the :y encoding. The default value is [].

Interactivity Options

  • :tooltip (boolean() | :data | :encoding) - The tooltip text string to show upon mouse hover or an object defining which fields should the tooltip be derived from. Can be one of the following:

    • :encoding - all fields from encoding are used
    • :data - all fields of the highlighted data point are used
    • true - same as :encoding
    • false, nil - no tooltip is used
  • :zoomable (boolean/0) - Whether the plot will be zoomable or not. If set to true you will be able to pan and zoom the plot with your mouse. You can reset to the original view with a double click. The default value is false.

Examples

Let's start with a default density heatmap on the penguins dataset:

Tucan.density_heatmap(:penguins, "Beak Length (mm)", "Beak Depth (mm)")
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://raw.githubusercontent.com/vega/vega-datasets/next/data/penguins.json"},"encoding":{"color":{"aggregate":"count","type":"quantitative"},"x":{"bin":true,"field":"Beak Length (mm)","type":"quantitative"},"y":{"bin":true,"field":"Beak Depth (mm)","type":"quantitative"}},"mark":{"fillOpacity":1,"type":"rect"}}

You can summarize over another field:

Tucan.density_heatmap(:penguins, "Beak Length (mm)", "Beak Depth (mm)",
  z: "Body Mass (g)",
  aggregate: :mean
)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://raw.githubusercontent.com/vega/vega-datasets/next/data/penguins.json"},"encoding":{"color":{"aggregate":"mean","field":"Body Mass (g)","type":"quantitative"},"x":{"bin":true,"field":"Beak Length (mm)","type":"quantitative"},"y":{"bin":true,"field":"Beak Depth (mm)","type":"quantitative"}},"mark":{"fillOpacity":1,"type":"rect"}}
Link to this function

donut(plotdata, field, category, opts \\ [])

View Source
@spec donut(
  plotdata :: plotdata(),
  field :: String.t(),
  category :: String.t(),
  opts :: keyword()
) :: VegaLite.t()

Draw a donut chart.

A donut chart is a circular visualization that resembles a pie chart but features a hole at its center. This central hole creates a donut shape, distinguishing it from traditional pie charts.

This is a wrapper around pie/4 that sets by default the :inner_radius.

Options

See pie/4

Examples

Tucan.donut(:barley, "yield", "site", aggregate: :sum, tooltip: true)
|> Tucan.facet_by(:column, "year", type: :nominal)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://vega.github.io/editor/data/barley.json"},"encoding":{"color":{"field":"site"},"column":{"field":"year","type":"nominal"},"theta":{"aggregate":"sum","field":"yield","type":"quantitative"}},"mark":{"fillOpacity":1,"innerRadius":50,"tooltip":true,"type":"arc"}}
Link to this function

errorband(plotdata, x, y, opts \\ [])

View Source
@spec errorband(
  plotdata :: plotdata(),
  x :: String.t(),
  y :: String.t(),
  opts :: keyword()
) ::
  VegaLite.t()

Draws an error band (confidence interval).

An error band summarizes an error range of quantitative values using a set of summary statistics, represented by area. Both x and y should be quantitative variables.

Options

  • :borders (boolean/0) - If set to true the error band's border will be added. The default value is false.

  • :extent - The extent of the rule. Can be one of the following:

    • :ci - Extend the rule to the confidence interval of the mean.
    • :stderr - The size of rule are set to the value of standard error, extending from the mean.
    • :stdev - The size of rule are set to the value of standard deviation, extending from the mean.
    • :iqr - Extend the rule to the q1 and q3.

    The default value is :stderr.

  • :interpolate (binary/0) - The line interpolation method to use for line and area marks. One of the following:

    • "linear" - piecewise linear segments, as in a poly-line.
    • "linear-closed" - close the linear segments to form a polygon.
    • "step" - alternate between horizontal and vertical segments, as in a step function.
    • "step-before" - alternate between vertical and horizontal segments, as in a step function.
    • "step-after" - alternate between horizontal and vertical segments, as in a step function.
    • "basis" - a B-spline, with control point duplication on the ends.
    • "basis-open" - an open B-spline; may not intersect the start or end.
    • "basis-closed" - a closed B-spline, as in a loop.
    • "cardinal" - a Cardinal spline, with control point duplication on the ends.
    • "cardinal-open" - an open Cardinal spline; may not intersect the start or end, but will intersect other control points.
    • "cardinal-closed" - a closed Cardinal spline, as in a loop.
    • "bundle" - equivalent to basis, except the tension parameter is used to straighten the spline.
    • "monotone" - cubic interpolation that preserves monotonicity in y.

Data Options

  • :only - A subset of fields to pick from the data. Applicable only if tabular data are provided.

Styling Options

  • :clip (boolean/0) - Whether a mark will be clipped to the enclosing group’s width and height.
  • :fill_color (String.t/0) - The fill color of the marks. This will override the color encoding if set.
  • :fill_opacity (number/0) - The fill opacity of the plotted elements. The default value is 1.
  • :height (pos_integer/0 or :container) - Height of the plot. Can either be the height in pixels or :container to indicate that the height of the plot should be the same as its surrounding container.
  • :line_color (String.t/0) - The color of the line
  • :stroke_dash (list of pos_integer/0) - An array of alternating stroke, space lengths in pixels for creating dashed or dotted lines.
  • :stroke_width (pos_integer/0) - The stroke width in pixels
  • :title (String.t/0) - The title of the graph
  • :width (pos_integer/0 or :container) - Width of the plot. Can either be the width in pixels or :container to indicate that the width of the plot should be the same as its surrounding container.

Encodings Custom Options

All Tucan plots are building a VegaLite specification based on some sane default parameters. Through these encodings options you are free to set any vega-lite supported option to any encoding channel of the plot.

Notice that if set they will be merged with any option set by the plot. Since they have a higher precedence they may override the default settings and affect the generated plot.

You can set an arbitrary keyword list. Notice that the contents are not validated.

  • :x (keyword/0) - Extra vega lite options for the :x encoding. The default value is [].
  • :y (keyword/0) - Extra vega lite options for the :y encoding. The default value is [].

Interactivity Options

  • :tooltip (boolean() | :data | :encoding) - The tooltip text string to show upon mouse hover or an object defining which fields should the tooltip be derived from. Can be one of the following:

    • :encoding - all fields from encoding are used
    • :data - all fields of the highlighted data point are used
    • true - same as :encoding
    • false, nil - no tooltip is used

Examples

Tucan.errorband(:cars, "Year", "Miles_per_Gallon", x: [time_unit: "year", type: :temporal])
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://vega.github.io/editor/data/cars.json"},"encoding":{"x":{"field":"Year","scale":{"zero":false},"timeUnit":"year","type":"temporal"},"y":{"field":"Miles_per_Gallon","scale":{"zero":false},"type":"quantitative"}},"mark":{"borders":false,"extent":"stderr","fillOpacity":1,"type":"errorband"}}

You can modify the look of the error band, change the :extent and include the borders if needed.

Tucan.errorband(:cars, "Year", "Miles_per_Gallon",
  extent: :ci,
  fill_color: "red",
  borders: true,
  x: [time_unit: "year", type: :temporal]
)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://vega.github.io/editor/data/cars.json"},"encoding":{"x":{"field":"Year","scale":{"zero":false},"timeUnit":"year","type":"temporal"},"y":{"field":"Miles_per_Gallon","scale":{"zero":false},"type":"quantitative"}},"mark":{"borders":[],"color":"red","extent":"ci","fillOpacity":1,"type":"errorband"}}

You can also change the look of the borders:

Tucan.errorband(:cars, "Year", "Miles_per_Gallon",
  extent: :ci,
  fill_color: "black",
  borders: true,
  line_color: "red",
  stroke_width: 3,
  stroke_dash: [7, 5],
  x: [time_unit: "year", type: :temporal]
)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://vega.github.io/editor/data/cars.json"},"encoding":{"x":{"field":"Year","scale":{"zero":false},"timeUnit":"year","type":"temporal"},"y":{"field":"Miles_per_Gallon","scale":{"zero":false},"type":"quantitative"}},"mark":{"borders":{"color":"red","strokeDash":[7,5],"strokeWidth":3},"color":"black","extent":"ci","fillOpacity":1,"type":"errorband"}}

Usually you want to combine the errorband with the mean trend line. You can use Tucan.layers/2 to combine it with a lineplot.

errorband =
  Tucan.errorband(:cars, "Year", "Miles_per_Gallon",
    extent: :ci,
    fill_color: "green",
    x: [time_unit: "year", type: :temporal]
  )

trendline =
  Tucan.lineplot(:cars, "Year", "Miles_per_Gallon",
    x: [time_unit: "year", type: :temporal],
    y: [aggregate: :mean]
  )

Tucan.layers([errorband, trendline])
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","layer":[{"data":{"url":"https://vega.github.io/editor/data/cars.json"},"encoding":{"x":{"field":"Year","scale":{"zero":false},"timeUnit":"year","type":"temporal"},"y":{"field":"Miles_per_Gallon","scale":{"zero":false},"type":"quantitative"}},"mark":{"borders":false,"color":"green","extent":"ci","fillOpacity":1,"type":"errorband"}},{"data":{"url":"https://vega.github.io/editor/data/cars.json"},"encoding":{"x":{"field":"Year","timeUnit":"year","type":"temporal"},"y":{"aggregate":"mean","field":"Miles_per_Gallon","type":"quantitative"}},"mark":{"fillOpacity":1,"type":"line"}}]}

Similar to other Tucan plots you can apply semantic grouping:

errorband =
  Tucan.errorband(:cars, "Year", "Miles_per_Gallon",
    extent: :ci,
    x: [time_unit: "year", type: :temporal]
  )

trendline =
  Tucan.lineplot(:cars, "Year", "Miles_per_Gallon",
    x: [time_unit: "year", type: :temporal],
    y: [aggregate: :mean]
  )

Tucan.layers([errorband, trendline])
|> Tucan.color_by("Origin")
|> Tucan.set_width(400)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","encoding":{"color":{"field":"Origin"}},"layer":[{"data":{"url":"https://vega.github.io/editor/data/cars.json"},"encoding":{"x":{"field":"Year","scale":{"zero":false},"timeUnit":"year","type":"temporal"},"y":{"field":"Miles_per_Gallon","scale":{"zero":false},"type":"quantitative"}},"mark":{"borders":false,"extent":"ci","fillOpacity":1,"type":"errorband"}},{"data":{"url":"https://vega.github.io/editor/data/cars.json"},"encoding":{"x":{"field":"Year","timeUnit":"year","type":"temporal"},"y":{"aggregate":"mean","field":"Miles_per_Gallon","type":"quantitative"}},"mark":{"fillOpacity":1,"type":"line"}}],"width":400}
Link to this function

errorbar(plotdata, field, opts \\ [])

View Source
@spec errorbar(plotdata :: plotdata(), field :: String.t(), opts :: keyword()) ::
  VegaLite.t()

Plots the errorbar for the given numerical variable field.

Error bars sho by default the standard error. It can also be explicitly specified by setting :extent to :stderr. The length of lower and upper rules represent standard error. By default, the rule marks expand from the mean.

Options

  • :extent - The extent of the rule. Can be one of the following:

    • :ci - Extend the rule to the confidence interval of the mean.
    • :stderr - The size of rule are set to the value of standard error, extending from the mean.
    • :stdev - The size of rule are set to the value of standard deviation, extending from the mean.
    • :iqr - Extend the rule to the q1 and q3.

    The default value is :stderr.

  • :group_by (String.t/0) - A field to be used for grouping the error bars by a category. If not set the plot will be one dimensional.

  • :points (boolean/0) - If set the means of the error bar are also included.

  • :ticks (boolean/0) - If set ticks will be included to the error bars ends

Data Options

  • :only - A subset of fields to pick from the data. Applicable only if tabular data are provided.

Styling Options

  • :clip (boolean/0) - Whether a mark will be clipped to the enclosing group’s width and height.
  • :fill_opacity (number/0) - The fill opacity of the plotted elements. The default value is 1.
  • :height (pos_integer/0 or :container) - Height of the plot. Can either be the height in pixels or :container to indicate that the height of the plot should be the same as its surrounding container.
  • :line_color (String.t/0) - The color of the line
  • :orient (atom/0) - The plot's orientation, can be either :horizontal or :vertical. The default value is :horizontal.
  • :point_color (String.t/0) - The color of the points if enabled. If not set defaults to the error bars color
  • :stroke_width (pos_integer/0) - The stroke width in pixels
  • :title (String.t/0) - The title of the graph
  • :width (pos_integer/0 or :container) - Width of the plot. Can either be the width in pixels or :container to indicate that the width of the plot should be the same as its surrounding container.

Encodings Custom Options

All Tucan plots are building a VegaLite specification based on some sane default parameters. Through these encodings options you are free to set any vega-lite supported option to any encoding channel of the plot.

Notice that if set they will be merged with any option set by the plot. Since they have a higher precedence they may override the default settings and affect the generated plot.

You can set an arbitrary keyword list. Notice that the contents are not validated.

  • :x (keyword/0) - Extra vega lite options for the :x encoding. The default value is [].
  • :y (keyword/0) - Extra vega lite options for the :y encoding. The default value is [].

Interactivity Options

  • :tooltip (boolean() | :data | :encoding) - The tooltip text string to show upon mouse hover or an object defining which fields should the tooltip be derived from. Can be one of the following:

    • :encoding - all fields from encoding are used
    • :data - all fields of the highlighted data point are used
    • true - same as :encoding
    • false, nil - no tooltip is used

Examples

A 1-d error bar:

Tucan.errorbar(:barley, "yield")
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","__tucan__":{"multilayer":true},"data":{"url":"https://vega.github.io/editor/data/barley.json"},"layer":[{"encoding":{"x":{"field":"yield","scale":{"zero":false},"type":"quantitative"}},"mark":{"extent":"stderr","fillOpacity":1,"type":"errorbar"}}]}

By setting the :group_by option you can show the error range of a continuous field broken down by categories.

Tucan.errorbar(:barley, "yield", group_by: "variety")
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","__tucan__":{"multilayer":true},"data":{"url":"https://vega.github.io/editor/data/barley.json"},"layer":[{"encoding":{"x":{"field":"yield","scale":{"zero":false},"type":"quantitative"},"y":{"field":"variety","type":"nominal"}},"mark":{"extent":"stderr","fillOpacity":1,"type":"errorbar"}}]}

You can change the orientation by setting the :orient option:

Tucan.errorbar(:barley, "yield", group_by: "variety", orient: :vertical)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","__tucan__":{"multilayer":true},"data":{"url":"https://vega.github.io/editor/data/barley.json"},"layer":[{"encoding":{"x":{"field":"variety","type":"nominal"},"y":{"field":"yield","scale":{"zero":false},"type":"quantitative"}},"mark":{"extent":"stderr","fillOpacity":1,"type":"errorbar"}}]}

By setting :ticks to true you can enable errorbar end ticks. Also you can overlay the means by setting :points to true.

Tucan.errorbar(:barley, "yield", group_by: "variety", ticks: true, points: true)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","__tucan__":{"multilayer":true},"data":{"url":"https://vega.github.io/editor/data/barley.json"},"layer":[{"encoding":{"x":{"field":"yield","scale":{"zero":false},"type":"quantitative"},"y":{"field":"variety","type":"nominal"}},"mark":{"extent":"stderr","fillOpacity":1,"ticks":true,"type":"errorbar"}},{"encoding":{"x":{"aggregate":"mean","field":"yield","type":"quantitative"},"y":{"field":"variety","type":"nominal"}},"mark":{"filled":true,"type":"point"}}]}

You can change the :extent value in order to configure how the error bars are extended. Below you can see all supported options:

valid_extent_values = [:ci, :stderr, :stdev, :iqr]

plots =
  for extent <- valid_extent_values do
    Tucan.errorbar(:barley, "yield", group_by: "variety", extent: extent)
    |> Tucan.set_title(inspect(extent) <> " extent")
    |> Tucan.Axes.set_enabled(:y, extent == :ci)
    |> Tucan.set_size(160, 160)
  end

Tucan.hconcat(plots)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","hconcat":[{"__tucan__":{"multilayer":true},"data":{"url":"https://vega.github.io/editor/data/barley.json"},"height":160,"layer":[{"encoding":{"x":{"field":"yield","scale":{"zero":false},"type":"quantitative"},"y":{"axis":[],"field":"variety","type":"nominal"}},"mark":{"extent":"ci","fillOpacity":1,"type":"errorbar"}}],"title":{"text":":ci extent"},"width":160},{"__tucan__":{"multilayer":true},"data":{"url":"https://vega.github.io/editor/data/barley.json"},"height":160,"layer":[{"encoding":{"x":{"field":"yield","scale":{"zero":false},"type":"quantitative"},"y":{"axis":null,"field":"variety","type":"nominal"}},"mark":{"extent":"stderr","fillOpacity":1,"type":"errorbar"}}],"title":{"text":":stderr extent"},"width":160},{"__tucan__":{"multilayer":true},"data":{"url":"https://vega.github.io/editor/data/barley.json"},"height":160,"layer":[{"encoding":{"x":{"field":"yield","scale":{"zero":false},"type":"quantitative"},"y":{"axis":null,"field":"variety","type":"nominal"}},"mark":{"extent":"stdev","fillOpacity":1,"type":"errorbar"}}],"title":{"text":":stdev extent"},"width":160},{"__tucan__":{"multilayer":true},"data":{"url":"https://vega.github.io/editor/data/barley.json"},"height":160,"layer":[{"encoding":{"x":{"field":"yield","scale":{"zero":false},"type":"quantitative"},"y":{"axis":null,"field":"variety","type":"nominal"}},"mark":{"extent":"iqr","fillOpacity":1,"type":"errorbar"}}],"title":{"text":":iqr extent"},"width":160}]}

You can use :line_color and :stroke_width to modify the look of the error bars:

Tucan.errorbar(:barley, "yield",
  group_by: "variety",
  line_color: "red",
  stroke_width: 3,
  ticks: true,
  points: true
)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","__tucan__":{"multilayer":true},"data":{"url":"https://vega.github.io/editor/data/barley.json"},"layer":[{"encoding":{"x":{"field":"yield","scale":{"zero":false},"type":"quantitative"},"y":{"field":"variety","type":"nominal"}},"mark":{"color":"red","extent":"stderr","fillOpacity":1,"rule":{"strokeWidth":3},"ticks":true,"type":"errorbar"}},{"encoding":{"x":{"aggregate":"mean","field":"yield","type":"quantitative"},"y":{"field":"variety","type":"nominal"}},"mark":{"color":"red","filled":true,"type":"point"}}]}

You can color categories by combining it with Tucan.color_by/3.

Tucan.errorbar(:barley, "yield", group_by: "variety", points: true)
|> Tucan.color_by("variety")
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","__tucan__":{"multilayer":true},"data":{"url":"https://vega.github.io/editor/data/barley.json"},"encoding":{"color":{"field":"variety"}},"layer":[{"encoding":{"x":{"field":"yield","scale":{"zero":false},"type":"quantitative"},"y":{"field":"variety","type":"nominal"}},"mark":{"extent":"stderr","fillOpacity":1,"type":"errorbar"}},{"encoding":{"x":{"aggregate":"mean","field":"yield","type":"quantitative"},"y":{"field":"variety","type":"nominal"}},"mark":{"filled":true,"type":"point"}}]}
Link to this function

heatmap(plotdata, x, y, color, opts \\ [])

View Source
@spec heatmap(
  plotdata :: plotdata(),
  x :: String.t(),
  y :: String.t(),
  color :: nil | String.t(),
  opts :: keyword()
) :: VegaLite.t()

Returns the specification of a heatmap.

A heatmap is a graphical representation of data where the individual values contained in a matrix are represented as colors.

It expects two categorical fields x, y which will be used for the axes and a numerical field color. If color is nil then the color represents the count of the observations for each x, y.

If an :aggregate is set this statistic will be used for encoding the color. If no :aggregate is set the color encodes by default the :mean of the data.

Options

  • :aggregate (atom/0) - The statistic that will be used for aggregating the observations within a heatmap tile. Defaults to :mean which in case of single data will encode the value of the color data field.

    Ignored if :color is set to nil.

  • :annotate (boolean/0) - If set to true then the values of each cell will be included in the plot. The default value is false.

Data Options

  • :only - A subset of fields to pick from the data. Applicable only if tabular data are provided.

Styling Options

  • :clip (boolean/0) - Whether a mark will be clipped to the enclosing group’s width and height.
  • :color_scheme (atom/0) - The color scheme to use, for supported color schemes check Tucan.Scale. Notice that this is just a helper option for easily setting color schemes. If you need to set specific colors or customize the scheme, use Tucan.Scale.set_color_scheme/3.
  • :fill_opacity (number/0) - The fill opacity of the plotted elements. The default value is 1.
  • :height (pos_integer/0 or :container) - Height of the plot. Can either be the height in pixels or :container to indicate that the height of the plot should be the same as its surrounding container.
  • :text_color - The color to be used for the textual annotations. Valid only if :annotate is set to true. Can be one of the following:
    • a string with the color to be used, e.g. "white"
    • a list of tuples of the form {low_threshold, upper_threshold, color} for conditionally setting the color based on the value of the annotated variable. low_threshold and upper_threshold can either be a number or nil. For example [{nil, 0, "green"}, {0, 5, "red"}, {5, nil, "white"}] will apply the following colors:
      • green for all items with value < 0
      • red for all items with value >= 0 && value < 5
      • white for all items with value >= 5 Notice that the low_threshold, upper_threshold correspond to the [low_threshold, upper_threshold) range.
  • :title (String.t/0) - The title of the graph
  • :width (pos_integer/0 or :container) - Width of the plot. Can either be the width in pixels or :container to indicate that the width of the plot should be the same as its surrounding container.

Encodings Custom Options

All Tucan plots are building a VegaLite specification based on some sane default parameters. Through these encodings options you are free to set any vega-lite supported option to any encoding channel of the plot.

Notice that if set they will be merged with any option set by the plot. Since they have a higher precedence they may override the default settings and affect the generated plot.

You can set an arbitrary keyword list. Notice that the contents are not validated.

  • :color (keyword/0) - Extra vega lite options for the :color encoding. The default value is [].
  • :text (keyword/0) - Extra vega lite options for the :text encoding. The default value is [].
  • :x (keyword/0) - Extra vega lite options for the :x encoding. The default value is [].
  • :y (keyword/0) - Extra vega lite options for the :y encoding. The default value is [].

Interactivity Options

  • :tooltip (boolean() | :data | :encoding) - The tooltip text string to show upon mouse hover or an object defining which fields should the tooltip be derived from. Can be one of the following:

    • :encoding - all fields from encoding are used
    • :data - all fields of the highlighted data point are used
    • true - same as :encoding
    • false, nil - no tooltip is used

Examples

A simple heatmap of two categorical variables, using a third one for the color values.

data = [
  %{"x" => "A", "y" => "K", "value" => 0.5},
  %{"x" => "A", "y" => "L", "value" => 1.5},
  %{"x" => "A", "y" => "M", "value" => 4.5},
  %{"x" => "B", "y" => "K", "value" => 1.5},
  %{"x" => "B", "y" => "L", "value" => 2.5},
  %{"x" => "B", "y" => "M", "value" => 0.5},
  %{"x" => "C", "y" => "K", "value" => -1.5},
  %{"x" => "C", "y" => "L", "value" => 5.5},
  %{"x" => "C", "y" => "M", "value" => 1.5}
]

Tucan.heatmap(data, "x", "y", "value", width: 200, height: 200)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","__tucan__":{"multilayer":true},"data":{"values":[{"value":0.5,"x":"A","y":"K"},{"value":1.5,"x":"A","y":"L"},{"value":4.5,"x":"A","y":"M"},{"value":1.5,"x":"B","y":"K"},{"value":2.5,"x":"B","y":"L"},{"value":0.5,"x":"B","y":"M"},{"value":-1.5,"x":"C","y":"K"},{"value":5.5,"x":"C","y":"L"},{"value":1.5,"x":"C","y":"M"}]},"height":200,"layer":[{"encoding":{"color":{"aggregate":"mean","field":"value","type":"quantitative"},"x":{"field":"x","type":"nominal"},"y":{"field":"y","type":"nominal"}},"mark":{"fillOpacity":1,"type":"rect"}}],"width":200}

You can change the color scheme:

Tucan.heatmap(:glue, "Task", "Model", "Score", color_scheme: :redyellowgreen, tooltip: true)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","__tucan__":{"multilayer":true},"data":{"url":"https://raw.githubusercontent.com/mwaskom/seaborn-data/master/glue.csv"},"layer":[{"encoding":{"color":{"aggregate":"mean","field":"Score","scale":{"scheme":"redyellowgreen"},"type":"quantitative"},"x":{"field":"Task","type":"nominal"},"y":{"field":"Model","type":"nominal"}},"mark":{"fillOpacity":1,"tooltip":true,"type":"rect"}}]}

Heatmaps are also useful for visualizing temporal data. Let's use a heatmap to examine how Seattle's max temperature changes over the year. On the x-axis we will encode the days of the month along the x-axis, and the months on the y-axis. We will aggregate over the max temperature for the color field. (example borrowed from here)

Tucan.heatmap(:weather, "date", "date", "temp_max",
  x: [type: :ordinal, time_unit: :date],
  y: [type: :ordinal, time_unit: :month],
  tooltip: true
)
|> Tucan.Scale.set_color_scheme(:redyellowblue, reverse: true)
|> Tucan.Axes.set_x_title("Day")
|> Tucan.Axes.set_y_title("Month")
|> Tucan.Legend.set_title(:color, "Avg Max Temp")
|> Tucan.set_title("Heatmap of Avg Max Temperatures in Seattle (2012-2015)")
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","__tucan__":{"multilayer":true},"data":{"url":"https://vega.github.io/editor/data/weather.csv"},"layer":[{"encoding":{"color":{"aggregate":"mean","field":"temp_max","legend":{"title":"Avg Max Temp"},"scale":{"reverse":true,"scheme":"redyellowblue"},"type":"quantitative"},"x":{"axis":{"title":"Day"},"field":"date","timeUnit":"date","type":"ordinal"},"y":{"axis":{"title":"Month"},"field":"date","timeUnit":"month","type":"ordinal"}},"mark":{"fillOpacity":1,"tooltip":true,"type":"rect"}}],"title":{"text":"Heatmap of Avg Max Temperatures in Seattle (2012-2015)"}}

You can enable annotations by setting the :annotate flag. Notice that you can conditionally color the annotation text by setting the :text_color option. It expects a list of tuples corresponding to {lower_threshold, upper_threshold, color}. Below we color white everything below 0 and black everything with a value >=0.

Tucan.heatmap(:weather, "date", "date", "temp_max",
  annotate: true,
  text_color: [{nil, 5, "white"}, {5, 25, "black"}, {25, nil, "white"}],
  x: [type: :ordinal, time_unit: :date],
  y: [type: :ordinal, time_unit: :month],
  text: [format: ".1f"],
  tooltip: true,
  width: 800
)
|> Tucan.Scale.set_color_scheme(:redyellowblue, reverse: true)
|> Tucan.Axes.set_x_title("Day")
|> Tucan.Axes.set_y_title("Month")
|> Tucan.Legend.set_title(:color, "Avg Max Temp")
|> Tucan.set_title("Heatmap of Avg Max Temperatures in Seattle (2012-2015)")
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","__tucan__":{"multilayer":true},"data":{"url":"https://vega.github.io/editor/data/weather.csv"},"layer":[{"encoding":{"color":{"aggregate":"mean","field":"temp_max","legend":{"title":"Avg Max Temp"},"scale":{"reverse":true,"scheme":"redyellowblue"},"type":"quantitative"},"x":{"axis":{"title":"Day"},"field":"date","timeUnit":"date","type":"ordinal"},"y":{"axis":{"title":"Month"},"field":"date","timeUnit":"month","type":"ordinal"}},"mark":{"fillOpacity":1,"tooltip":true,"type":"rect"}},{"encoding":{"color":{"aggregate":"mean","condition":[{"test":"datum['mean_temp_max'] < 5","value":"white"},{"test":"datum['mean_temp_max'] >= 5 && datum['mean_temp_max'] < 25","value":"black"},{"test":"datum['mean_temp_max'] >= 25","value":"white"},{"test":"true","value":"black"}],"field":"temp_max","legend":{"title":"Avg Max Temp"},"scale":{"reverse":true,"scheme":"redyellowblue"},"type":"quantitative"},"text":{"aggregate":"mean","field":"temp_max","format":".1f","type":"quantitative"},"x":{"axis":{"title":"Day"},"field":"date","timeUnit":"date","type":"ordinal"},"y":{"axis":{"title":"Month"},"field":"date","timeUnit":"month","type":"ordinal"}},"mark":"text"}],"title":{"text":"Heatmap of Avg Max Temperatures in Seattle (2012-2015)"},"width":800}
Link to this function

histogram(plotdata, field, opts \\ [])

View Source
@spec histogram(plotdata :: plotdata(), field :: String.t(), opts :: keyword()) ::
  VegaLite.t()

Plots a histogram.

See also density/3

Options

  • :extent - A two-element ([min, max]) array indicating the range of desired bin values.
  • :maxbins (integer/0) - Maximum number of bins.
  • :orient - Histogram's orientation. It specifies the axis along which the field values are plotted. The default value is :horizontal.
  • :relative (boolean/0) - If set a relative frequency histogram is generated. The default value is false.
  • :stacked (boolean/0) - If set it will stack the group histograms instead of layering one over another. Valid only if a semantic grouping has been applied.
  • :step - An exact step size to use between bins. If provided, options such as maxbins will be ignored.

Data Grouping Options

  • :color_by (String.t/0) - The field to group observations by. This will used for coloring the histogram if set.

Data Options

  • :only - A subset of fields to pick from the data. Applicable only if tabular data are provided.

Styling Options

  • :clip (boolean/0) - Whether a mark will be clipped to the enclosing group’s width and height.
  • :corner_radius (non_neg_integer/0) - The radius in pixels of rounded rectangles. The end radius is affected:
    • For vertical bars, top-left and top-right corner radius.
    • For horizontal bars, top-right and bottom-right corner radius.
  • :fill_color (String.t/0) - The fill color of the marks. This will override the color encoding if set.
  • :fill_opacity (number/0) - The fill opacity of the plotted elements. The default value is 1.
  • :height (pos_integer/0 or :container) - Height of the plot. Can either be the height in pixels or :container to indicate that the height of the plot should be the same as its surrounding container.
  • :title (String.t/0) - The title of the graph
  • :width (pos_integer/0 or :container) - Width of the plot. Can either be the width in pixels or :container to indicate that the width of the plot should be the same as its surrounding container.

Encodings Custom Options

All Tucan plots are building a VegaLite specification based on some sane default parameters. Through these encodings options you are free to set any vega-lite supported option to any encoding channel of the plot.

Notice that if set they will be merged with any option set by the plot. Since they have a higher precedence they may override the default settings and affect the generated plot.

You can set an arbitrary keyword list. Notice that the contents are not validated.

  • :color (keyword/0) - Extra vega lite options for the :color encoding. The default value is [].
  • :x (keyword/0) - Extra vega lite options for the :x encoding. The default value is [].
  • :x2 (keyword/0) - Extra vega lite options for the :x2 encoding. The default value is [].
  • :y (keyword/0) - Extra vega lite options for the :y encoding. The default value is [].
  • :y2 (keyword/0) - Extra vega lite options for the :y2 encoding. The default value is [].

Interactivity Options

  • :tooltip (boolean() | :data | :encoding) - The tooltip text string to show upon mouse hover or an object defining which fields should the tooltip be derived from. Can be one of the following:

    • :encoding - all fields from encoding are used
    • :data - all fields of the highlighted data point are used
    • true - same as :encoding
    • false, nil - no tooltip is used
  • :zoomable (boolean/0) - Whether the plot will be zoomable or not. If set to true you will be able to pan and zoom the plot with your mouse. You can reset to the original view with a double click. The default value is false.

Examples

Histogram of Horsepower

Tucan.histogram(:cars, "Horsepower")
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","__tucan__":{"plot":"histogram"},"data":{"url":"https://vega.github.io/editor/data/cars.json"},"encoding":{"x":{"bin":{"binned":true},"field":"bin_Horsepower","title":"Horsepower"},"x2":{"field":"bin_Horsepower_end"},"y":{"field":"count_Horsepower","stack":null,"type":"quantitative"}},"mark":{"fillOpacity":1,"type":"bar"},"transform":[{"as":"bin_Horsepower","bin":true,"field":"Horsepower"},{"aggregate":[{"as":"count_Horsepower","op":"count"}],"groupby":["bin_Horsepower","bin_Horsepower_end"]}]}

You can flip the plot by setting the :orient option to :vertical:

Tucan.histogram(:cars, "Horsepower", orient: :vertical)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","__tucan__":{"plot":"histogram"},"data":{"url":"https://vega.github.io/editor/data/cars.json"},"encoding":{"x":{"field":"count_Horsepower","stack":null,"type":"quantitative"},"y":{"bin":{"binned":true},"field":"bin_Horsepower","title":"Horsepower"},"y2":{"field":"bin_Horsepower_end"}},"mark":{"fillOpacity":1,"type":"bar"},"transform":[{"as":"bin_Horsepower","bin":true,"field":"Horsepower"},{"aggregate":[{"as":"count_Horsepower","op":"count"}],"groupby":["bin_Horsepower","bin_Horsepower_end"]}]}

You can also modify the default color and add a radius to the histogram bars:

Tucan.histogram(:cars, "Horsepower", orient: :vertical, fill_color: "red", corner_radius: 5)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","__tucan__":{"plot":"histogram"},"data":{"url":"https://vega.github.io/editor/data/cars.json"},"encoding":{"x":{"field":"count_Horsepower","stack":null,"type":"quantitative"},"y":{"bin":{"binned":true},"field":"bin_Horsepower","title":"Horsepower"},"y2":{"field":"bin_Horsepower_end"}},"mark":{"color":"red","cornerRadiusEnd":5,"fillOpacity":1,"type":"bar"},"transform":[{"as":"bin_Horsepower","bin":true,"field":"Horsepower"},{"aggregate":[{"as":"count_Horsepower","op":"count"}],"groupby":["bin_Horsepower","bin_Horsepower_end"]}]}

By setting the :relative flag you can get a relative frequency histogram:

Tucan.histogram(:cars, "Horsepower", relative: true)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","__tucan__":{"plot":"histogram"},"data":{"url":"https://vega.github.io/editor/data/cars.json"},"encoding":{"x":{"bin":{"binned":true},"field":"bin_Horsepower","title":"Horsepower"},"x2":{"field":"bin_Horsepower_end"},"y":{"axis":{"format":".1~%"},"field":"percent_Horsepower","stack":null,"title":"Relative Frequency","type":"quantitative"}},"mark":{"fillOpacity":1,"type":"bar"},"transform":[{"as":"bin_Horsepower","bin":true,"field":"Horsepower"},{"aggregate":[{"as":"count_Horsepower","op":"count"}],"groupby":["bin_Horsepower","bin_Horsepower_end"]},{"groupby":[],"joinaggregate":[{"as":"total_count_Horsepower","field":"count_Horsepower","op":"sum"}]},{"as":"percent_Horsepower","calculate":"datum.count_Horsepower/datum.total_count_Horsepower"}]}

You can increase the number of bins by settings the maxbins or the step options:

Tucan.histogram(:cars, "Horsepower", step: 5)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","__tucan__":{"plot":"histogram"},"data":{"url":"https://vega.github.io/editor/data/cars.json"},"encoding":{"x":{"bin":{"binned":true},"field":"bin_Horsepower","title":"Horsepower"},"x2":{"field":"bin_Horsepower_end"},"y":{"field":"count_Horsepower","stack":null,"type":"quantitative"}},"mark":{"fillOpacity":1,"type":"bar"},"transform":[{"as":"bin_Horsepower","bin":{"step":5},"field":"Horsepower"},{"aggregate":[{"as":"count_Horsepower","op":"count"}],"groupby":["bin_Horsepower","bin_Horsepower_end"]}]}

You can draw multiple histograms by grouping the observations by a second categorical variable:

Tucan.histogram(:cars, "Horsepower", color_by: "Origin", fill_opacity: 0.5)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","__tucan__":{"plot":"histogram"},"data":{"url":"https://vega.github.io/editor/data/cars.json"},"encoding":{"color":{"field":"Origin"},"x":{"bin":{"binned":true},"field":"bin_Horsepower","title":"Horsepower"},"x2":{"field":"bin_Horsepower_end"},"y":{"field":"count_Horsepower","stack":null,"type":"quantitative"}},"mark":{"fillOpacity":0.5,"type":"bar"},"transform":[{"as":"bin_Horsepower","bin":true,"field":"Horsepower"},{"aggregate":[{"as":"count_Horsepower","op":"count"}],"groupby":["bin_Horsepower","bin_Horsepower_end","Origin"]}]}

By default the histograms are plotted layered, but you can also stack them:

Tucan.histogram(:cars, "Horsepower", color_by: "Origin", fill_opacity: 0.5, stacked: true)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","__tucan__":{"plot":"histogram"},"data":{"url":"https://vega.github.io/editor/data/cars.json"},"encoding":{"color":{"field":"Origin"},"x":{"bin":{"binned":true},"field":"bin_Horsepower","title":"Horsepower"},"x2":{"field":"bin_Horsepower_end"},"y":{"field":"count_Horsepower","stack":true,"type":"quantitative"}},"mark":{"fillOpacity":0.5,"type":"bar"},"transform":[{"as":"bin_Horsepower","bin":true,"field":"Horsepower"},{"aggregate":[{"as":"count_Horsepower","op":"count"}],"groupby":["bin_Horsepower","bin_Horsepower_end","Origin"]}]}

or you can facet it, in order to make the histograms more clear:

histograms =
  Tucan.histogram(:cars, "Horsepower", color_by: "Origin", tooltip: true)
  |> Tucan.facet_by(:column, "Origin")

relative_histograms =
  Tucan.histogram(:cars, "Horsepower", relative: true, color_by: "Origin", tooltip: true)
  |> Tucan.facet_by(:column, "Origin")

Tucan.vconcat([histograms, relative_histograms])
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","vconcat":[{"__tucan__":{"plot":"histogram"},"data":{"url":"https://vega.github.io/editor/data/cars.json"},"encoding":{"color":{"field":"Origin"},"column":{"field":"Origin"},"x":{"bin":{"binned":true},"field":"bin_Horsepower","title":"Horsepower"},"x2":{"field":"bin_Horsepower_end"},"y":{"field":"count_Horsepower","stack":null,"type":"quantitative"}},"mark":{"fillOpacity":1,"tooltip":true,"type":"bar"},"transform":[{"as":"bin_Horsepower","bin":true,"field":"Horsepower"},{"aggregate":[{"as":"count_Horsepower","op":"count"}],"groupby":["bin_Horsepower","bin_Horsepower_end","Origin"]}]},{"__tucan__":{"plot":"histogram"},"data":{"url":"https://vega.github.io/editor/data/cars.json"},"encoding":{"color":{"field":"Origin"},"column":{"field":"Origin"},"x":{"bin":{"binned":true},"field":"bin_Horsepower","title":"Horsepower"},"x2":{"field":"bin_Horsepower_end"},"y":{"axis":{"format":".1~%"},"field":"percent_Horsepower","stack":null,"title":"Relative Frequency","type":"quantitative"}},"mark":{"fillOpacity":1,"tooltip":true,"type":"bar"},"transform":[{"as":"bin_Horsepower","bin":true,"field":"Horsepower"},{"aggregate":[{"as":"count_Horsepower","op":"count"}],"groupby":["bin_Horsepower","bin_Horsepower_end","Origin"]},{"groupby":["Origin"],"joinaggregate":[{"as":"total_count_Horsepower","field":"count_Horsepower","op":"sum"}]},{"as":"percent_Horsepower","calculate":"datum.count_Horsepower/datum.total_count_Horsepower"}]}]}
Link to this function

lineplot(plotdata, x, y, opts \\ [])

View Source
@spec lineplot(plotdata :: plotdata(), x :: field(), y :: field(), opts :: keyword()) ::
  VegaLite.t()

Draw a line plot between x and y

Both x and y are considered numerical variables.

Options

  • :interpolate (binary/0) - The line interpolation method to use for line and area marks. One of the following:
    • "linear" - piecewise linear segments, as in a poly-line.
    • "linear-closed" - close the linear segments to form a polygon.
    • "step" - alternate between horizontal and vertical segments, as in a step function.
    • "step-before" - alternate between vertical and horizontal segments, as in a step function.
    • "step-after" - alternate between horizontal and vertical segments, as in a step function.
    • "basis" - a B-spline, with control point duplication on the ends.
    • "basis-open" - an open B-spline; may not intersect the start or end.
    • "basis-closed" - a closed B-spline, as in a loop.
    • "cardinal" - a Cardinal spline, with control point duplication on the ends.
    • "cardinal-open" - an open Cardinal spline; may not intersect the start or end, but will intersect other control points.
    • "cardinal-closed" - a closed Cardinal spline, as in a loop.
    • "bundle" - equivalent to basis, except the tension parameter is used to straighten the spline.
    • "monotone" - cubic interpolation that preserves monotonicity in y.
  • :tension (number/0) - Depending on the interpolation type, sets the tension parameter

Data Grouping Options

  • :color_by (String.t/0) - If set a data field that will be used for coloring the data. It is considered :nominal by default.
  • :group_by (String.t/0) - A field to group by the lines without affecting the style of it.

Data Options

  • :only - A subset of fields to pick from the data. Applicable only if tabular data are provided.

Styling Options

  • :clip (boolean/0) - Whether a mark will be clipped to the enclosing group’s width and height.
  • :fill_opacity (number/0) - The fill opacity of the plotted elements. The default value is 1.
  • :filled (boolean/0) - Whether the points will be filled or not. Valid only if :points is set. The default value is true.
  • :height (pos_integer/0 or :container) - Height of the plot. Can either be the height in pixels or :container to indicate that the height of the plot should be the same as its surrounding container.
  • :line_color (String.t/0) - The color of the line
  • :point_color (String.t/0) - The color of the points, if :points is set to true.
  • :points (boolean/0) - Whether points will be included in the chart. The default value is false.
  • :stroke_dash (list of pos_integer/0) - An array of alternating stroke, space lengths in pixels for creating dashed or dotted lines.
  • :stroke_width (pos_integer/0) - The stroke width in pixels
  • :title (String.t/0) - The title of the graph
  • :width (pos_integer/0 or :container) - Width of the plot. Can either be the width in pixels or :container to indicate that the width of the plot should be the same as its surrounding container.

Encodings Custom Options

All Tucan plots are building a VegaLite specification based on some sane default parameters. Through these encodings options you are free to set any vega-lite supported option to any encoding channel of the plot.

Notice that if set they will be merged with any option set by the plot. Since they have a higher precedence they may override the default settings and affect the generated plot.

You can set an arbitrary keyword list. Notice that the contents are not validated.

  • :color (keyword/0) - Extra vega lite options for the :color encoding. The default value is [].
  • :x (keyword/0) - Extra vega lite options for the :x encoding. The default value is [].
  • :y (keyword/0) - Extra vega lite options for the :y encoding. The default value is [].

Interactivity Options

  • :tooltip (boolean() | :data | :encoding) - The tooltip text string to show upon mouse hover or an object defining which fields should the tooltip be derived from. Can be one of the following:

    • :encoding - all fields from encoding are used
    • :data - all fields of the highlighted data point are used
    • true - same as :encoding
    • false, nil - no tooltip is used
  • :zoomable (boolean/0) - Whether the plot will be zoomable or not. If set to true you will be able to pan and zoom the plot with your mouse. You can reset to the original view with a double click. The default value is false.

Examples

Plotting a simple line chart of Google stock price over time. Notice how we change the x axis type from the default (:quantitative) to :temporal using the generic :x channel configuration option:

Tucan.lineplot(:stocks, "date", "price", x: [type: :temporal])
|> VegaLite.transform(filter: "datum.symbol==='GOOG'")
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://vega.github.io/editor/data/stocks.csv"},"encoding":{"x":{"field":"date","type":"temporal"},"y":{"field":"price","type":"quantitative"}},"mark":{"fillOpacity":1,"type":"line"},"transform":[{"filter":"datum.symbol==='GOOG'"}]}

You could plot all stocks of the dataset with different colors by setting the :color_by option. If you do not want to color lines differently, you can pass the :group_by option instead of :color_by:

left = Tucan.lineplot(:stocks, "date", "price", x: [type: :temporal], color_by: "symbol")
right = Tucan.lineplot(:stocks, "date", "price", x: [type: :temporal], group_by: "symbol")

Tucan.hconcat([left, right])
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","hconcat":[{"data":{"url":"https://vega.github.io/editor/data/stocks.csv"},"encoding":{"color":{"field":"symbol"},"x":{"field":"date","type":"temporal"},"y":{"field":"price","type":"quantitative"}},"mark":{"fillOpacity":1,"type":"line"}},{"data":{"url":"https://vega.github.io/editor/data/stocks.csv"},"encoding":{"detail":{"field":"symbol","type":"nominal"},"x":{"field":"date","type":"temporal"},"y":{"field":"price","type":"quantitative"}},"mark":{"fillOpacity":1,"type":"line"}}]}

You can also overlay the points by setting the :points and :filled opts. Notice that below we plot by year and aggregating the y values:

filled_points =
  Tucan.lineplot(:stocks, "date", "price",
    x: [type: :temporal, time_unit: :year],
    y: [aggregate: :mean],
    color_by: "symbol",
    points: true,
    tooltip: true,
    width: 300
  )

stroked_points =
  Tucan.lineplot(:stocks, "date", "price",
    x: [type: :temporal, time_unit: :year],
    y: [aggregate: :mean],
    color_by: "symbol",
    points: true,
    filled: false,
    tooltip: true,
    width: 300
  )

Tucan.hconcat([filled_points, stroked_points])
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","hconcat":[{"data":{"url":"https://vega.github.io/editor/data/stocks.csv"},"encoding":{"color":{"field":"symbol"},"x":{"field":"date","timeUnit":"year","type":"temporal"},"y":{"aggregate":"mean","field":"price","type":"quantitative"}},"mark":{"fillOpacity":1,"point":[],"tooltip":true,"type":"line"},"width":300},{"data":{"url":"https://vega.github.io/editor/data/stocks.csv"},"encoding":{"color":{"field":"symbol"},"x":{"field":"date","timeUnit":"year","type":"temporal"},"y":{"aggregate":"mean","field":"price","type":"quantitative"}},"mark":{"fillOpacity":1,"point":{"fill":"white","filled":false},"tooltip":true,"type":"line"},"width":300}]}

You can configure the style of the lines using :stroke_dash, :stroke_width and :line_color options.

data =
  for i <- 0..100, x = 0.1 * i do
    %{x: x, cos: :math.cos(x), sin: :math.sin(x)}
  end

Tucan.layers([
  Tucan.lineplot(data, "x", "cos", stroke_width: 3, stroke_dash: [5, 2], line_color: "red"),
  Tucan.lineplot(data, "x", "sin", stroke_width: 2, stroke_dash: [5, 3, 2], line_color: "green")
])
|> Tucan.set_width(300)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","layer":[{"data":{"values":[{"cos":1.0,"sin":0.0,"x":0.0},{"cos":0.9950041652780258,"sin":0.09983341664682815,"x":0.1},{"cos":0.9800665778412416,"sin":0.19866933079506122,"x":0.2},{"cos":0.955336489125606,"sin":0.2955202066613396,"x":0.30000000000000004},{"cos":0.9210609940028851,"sin":0.3894183423086505,"x":0.4},{"cos":0.8775825618903728,"sin":0.479425538604203,"x":0.5},{"cos":0.8253356149096782,"sin":0.5646424733950355,"x":0.6000000000000001},{"cos":0.7648421872844884,"sin":0.6442176872376911,"x":0.7000000000000001},{"cos":0.6967067093471654,"sin":0.7173560908995228,"x":0.8},{"cos":0.6216099682706644,"sin":0.7833269096274834,"x":0.9},{"cos":0.5403023058681398,"sin":0.8414709848078965,"x":1.0},{"cos":0.4535961214255773,"sin":0.8912073600614354,"x":1.1},{"cos":0.3623577544766734,"sin":0.9320390859672264,"x":1.2000000000000002},{"cos":0.26749882862458735,"sin":0.963558185417193,"x":1.3},{"cos":0.16996714290024081,"sin":0.9854497299884603,"x":1.4000000000000001},{"cos":0.0707372016677029,"sin":0.9974949866040544,"x":1.5},{"cos":-0.029199522301288815,"sin":0.9995736030415051,"x":1.6},{"cos":-0.12884449429552486,"sin":0.9916648104524686,"x":1.7000000000000002},{"cos":-0.2272020946930871,"sin":0.9738476308781951,"x":1.8},{"cos":-0.3232895668635035,"sin":0.9463000876874145,"x":1.9000000000000001},{"cos":-0.4161468365471424,"sin":0.9092974268256817,"x":2.0},{"cos":-0.5048461045998576,"sin":0.8632093666488737,"x":2.1},{"cos":-0.5885011172553458,"sin":0.8084964038195901,"x":2.2},{"cos":-0.6662760212798244,"sin":0.74570521217672,"x":2.3000000000000003},{"cos":-0.7373937155412458,"sin":0.6754631805511506,"x":2.4000000000000004},{"cos":-0.8011436155469337,"sin":0.5984721441039564,"x":2.5},{"cos":-0.8568887533689473,"sin":0.5155013718214642,"x":2.6},{"cos":-0.9040721420170612,"sin":0.4273798802338298,"x":2.7},{"cos":-0.9422223406686583,"sin":0.33498815015590466,"x":2.8000000000000003},{"cos":-0.9709581651495907,"sin":0.23924932921398198,"x":2.9000000000000004},{"cos":-0.9899924966004454,"sin":0.1411200080598672,"x":3.0},{"cos":-0.9991351502732795,"sin":0.04158066243329049,"x":3.1},{"cos":-0.9982947757947531,"sin":-0.058374143427580086,"x":3.2},{"cos":-0.9874797699088649,"sin":-0.15774569414324865,"x":3.3000000000000003},{"cos":-0.9667981925794609,"sin":-0.25554110202683167,"x":3.4000000000000004},{"cos":-0.9364566872907963,"sin":-0.35078322768961984,"x":3.5},{"cos":-0.896758416334147,"sin":-0.44252044329485246,"x":3.6},{"cos":-0.848100031710408,"sin":-0.5298361409084934,"x":3.7},{"cos":-0.7909677119144165,"sin":-0.6118578909427193,"x":3.8000000000000003},{"cos":-0.7259323042001399,"sin":-0.6877661591839741,"x":3.9000000000000004},{"cos":-0.6536436208636119,"sin":-0.7568024953079283,"x":4.0},{"cos":-0.5748239465332685,"sin":-0.8182771110644108,"x":4.1000000000000005},{"cos":-0.4902608213406994,"sin":-0.8715757724135882,"x":4.2},{"cos":-0.40079917207997545,"sin":-0.9161659367494549,"x":4.3},{"cos":-0.30733286997841935,"sin":-0.9516020738895161,"x":4.4},{"cos":-0.2107957994307797,"sin":-0.977530117665097,"x":4.5},{"cos":-0.112152526935054,"sin":-0.9936910036334645,"x":4.6000000000000005},{"cos":-0.01238866346289056,"sin":-0.9999232575641008,"x":4.7},{"cos":0.08749898343944727,"sin":-0.9961646088358406,"x":4.800000000000001},{"cos":0.18651236942257576,"sin":-0.9824526126243325,"x":4.9},{"cos":0.28366218546322625,"sin":-0.9589242746631385,"x":5.0},{"cos":0.37797774271298107,"sin":-0.9258146823277321,"x":5.1000000000000005},{"cos":0.4685166713003771,"sin":-0.8834546557201531,"x":5.2},{"cos":0.5543743361791615,"sin":-0.8322674422239008,"x":5.300000000000001},{"cos":0.6346928759426347,"sin":-0.7727644875559871,"x":5.4},{"cos":0.70866977429126,"sin":-0.7055403255703919,"x":5.5},{"cos":0.7755658785102502,"sin":-0.631266637872321,"x":5.6000000000000005},{"cos":0.8347127848391598,"sin":-0.5506855425976376,"x":5.7},{"cos":0.8855195169413194,"sin":-0.4646021794137566,"x":5.800000000000001},{"cos":0.9274784307440359,"sin":-0.373876664830236,"x":5.9},{"cos":0.960170286650366,"sin":-0.27941549819892586,"x":6.0},{"cos":0.9832684384425847,"sin":-0.18216250427209502,"x":6.1000000000000005},{"cos":0.9965420970232175,"sin":-0.0830894028174964,"x":6.2},{"cos":0.9998586363834151,"sin":0.0168139004843506,"x":6.300000000000001},{"cos":0.9931849187581926,"sin":0.11654920485049364,"x":6.4},{"cos":0.9765876257280235,"sin":0.21511998808781552,"x":6.5},{"cos":0.9502325919585293,"sin":0.3115413635133787,"x":6.6000000000000005},{"cos":0.9143831482353194,"sin":0.4048499206165983,"x":6.7},{"cos":0.8693974903498248,"sin":0.49411335113860894,"x":6.800000000000001},{"cos":0.8157251001253569,"sin":0.5784397643882002,"x":6.9},{"cos":0.7539022543433046,"sin":0.6569865987187891,"x":7.0},{"cos":0.6845466664428059,"sin":0.7289690401258765,"x":7.1000000000000005},{"cos":0.6083513145322546,"sin":0.7936678638491531,"x":7.2},{"cos":0.5260775173811045,"sin":0.850436620628565,"x":7.300000000000001},{"cos":0.43854732757439036,"sin":0.8987080958116269,"x":7.4},{"cos":0.3466353178350258,"sin":0.9379999767747389,"x":7.5},{"cos":0.25125984258225487,"sin":0.9679196720314865,"x":7.6000000000000005},{"cos":0.15337386203786435,"sin":0.9881682338770004,"x":7.7},{"cos":0.05395542056264886,"sin":0.998543345374605,"x":7.800000000000001},{"cos":-0.04600212563953695,"sin":0.998941341839772,"x":7.9},{"cos":-0.14550003380861354,"sin":0.9893582466233818,"x":8.0},{"cos":-0.2435441537357911,"sin":0.9698898108450863,"x":8.1},{"cos":-0.33915486098383624,"sin":0.9407305566797726,"x":8.200000000000001},{"cos":-0.43137684497062084,"sin":0.9021718337562934,"x":8.3},{"cos":-0.5192886541166856,"sin":0.8545989080882804,"x":8.4},{"cos":-0.6020119026848236,"sin":0.7984871126234903,"x":8.5},{"cos":-0.6787200473200125,"sin":0.7343970978741134,"x":8.6},{"cos":-0.7486466455973999,"sin":0.662969230082182,"x":8.700000000000001},{"cos":-0.811093014061656,"sin":0.5849171928917617,"x":8.8},{"cos":-0.8654352092411123,"sin":0.5010208564578846,"x":8.9},{"cos":-0.9111302618846769,"sin":0.4121184852417566,"x":9.0},{"cos":-0.9477216021311119,"sin":0.3190983623493521,"x":9.1},{"cos":-0.974843621404164,"sin":0.22288991410024592,"x":9.200000000000001},{"cos":-0.9922253254526034,"sin":0.1244544235070617,"x":9.3},{"cos":-0.9996930420352065,"sin":0.024775425453357765,"x":9.4},{"cos":-0.9971721561963784,"sin":-0.0751511204618093,"x":9.5},{"cos":-0.9846878557941267,"sin":-0.1743267812229814,"x":9.600000000000001},{"cos":-0.9623648798313097,"sin":-0.2717606264109442,"x":9.700000000000001},{"cos":-0.9304262721047533,"sin":-0.36647912925192844,"x":9.8},{"cos":-0.8891911526253609,"sin":-0.4575358937753214,"x":9.9},{"cos":-0.8390715290764524,"sin":-0.5440211108893698,"x":10.0}]},"encoding":{"x":{"field":"x","type":"quantitative"},"y":{"field":"cos","type":"quantitative"}},"mark":{"color":"red","fillOpacity":1,"strokeDash":[5,2],"strokeWidth":3,"type":"line"}},{"data":{"values":[{"cos":1.0,"sin":0.0,"x":0.0},{"cos":0.9950041652780258,"sin":0.09983341664682815,"x":0.1},{"cos":0.9800665778412416,"sin":0.19866933079506122,"x":0.2},{"cos":0.955336489125606,"sin":0.2955202066613396,"x":0.30000000000000004},{"cos":0.9210609940028851,"sin":0.3894183423086505,"x":0.4},{"cos":0.8775825618903728,"sin":0.479425538604203,"x":0.5},{"cos":0.8253356149096782,"sin":0.5646424733950355,"x":0.6000000000000001},{"cos":0.7648421872844884,"sin":0.6442176872376911,"x":0.7000000000000001},{"cos":0.6967067093471654,"sin":0.7173560908995228,"x":0.8},{"cos":0.6216099682706644,"sin":0.7833269096274834,"x":0.9},{"cos":0.5403023058681398,"sin":0.8414709848078965,"x":1.0},{"cos":0.4535961214255773,"sin":0.8912073600614354,"x":1.1},{"cos":0.3623577544766734,"sin":0.9320390859672264,"x":1.2000000000000002},{"cos":0.26749882862458735,"sin":0.963558185417193,"x":1.3},{"cos":0.16996714290024081,"sin":0.9854497299884603,"x":1.4000000000000001},{"cos":0.0707372016677029,"sin":0.9974949866040544,"x":1.5},{"cos":-0.029199522301288815,"sin":0.9995736030415051,"x":1.6},{"cos":-0.12884449429552486,"sin":0.9916648104524686,"x":1.7000000000000002},{"cos":-0.2272020946930871,"sin":0.9738476308781951,"x":1.8},{"cos":-0.3232895668635035,"sin":0.9463000876874145,"x":1.9000000000000001},{"cos":-0.4161468365471424,"sin":0.9092974268256817,"x":2.0},{"cos":-0.5048461045998576,"sin":0.8632093666488737,"x":2.1},{"cos":-0.5885011172553458,"sin":0.8084964038195901,"x":2.2},{"cos":-0.6662760212798244,"sin":0.74570521217672,"x":2.3000000000000003},{"cos":-0.7373937155412458,"sin":0.6754631805511506,"x":2.4000000000000004},{"cos":-0.8011436155469337,"sin":0.5984721441039564,"x":2.5},{"cos":-0.8568887533689473,"sin":0.5155013718214642,"x":2.6},{"cos":-0.9040721420170612,"sin":0.4273798802338298,"x":2.7},{"cos":-0.9422223406686583,"sin":0.33498815015590466,"x":2.8000000000000003},{"cos":-0.9709581651495907,"sin":0.23924932921398198,"x":2.9000000000000004},{"cos":-0.9899924966004454,"sin":0.1411200080598672,"x":3.0},{"cos":-0.9991351502732795,"sin":0.04158066243329049,"x":3.1},{"cos":-0.9982947757947531,"sin":-0.058374143427580086,"x":3.2},{"cos":-0.9874797699088649,"sin":-0.15774569414324865,"x":3.3000000000000003},{"cos":-0.9667981925794609,"sin":-0.25554110202683167,"x":3.4000000000000004},{"cos":-0.9364566872907963,"sin":-0.35078322768961984,"x":3.5},{"cos":-0.896758416334147,"sin":-0.44252044329485246,"x":3.6},{"cos":-0.848100031710408,"sin":-0.5298361409084934,"x":3.7},{"cos":-0.7909677119144165,"sin":-0.6118578909427193,"x":3.8000000000000003},{"cos":-0.7259323042001399,"sin":-0.6877661591839741,"x":3.9000000000000004},{"cos":-0.6536436208636119,"sin":-0.7568024953079283,"x":4.0},{"cos":-0.5748239465332685,"sin":-0.8182771110644108,"x":4.1000000000000005},{"cos":-0.4902608213406994,"sin":-0.8715757724135882,"x":4.2},{"cos":-0.40079917207997545,"sin":-0.9161659367494549,"x":4.3},{"cos":-0.30733286997841935,"sin":-0.9516020738895161,"x":4.4},{"cos":-0.2107957994307797,"sin":-0.977530117665097,"x":4.5},{"cos":-0.112152526935054,"sin":-0.9936910036334645,"x":4.6000000000000005},{"cos":-0.01238866346289056,"sin":-0.9999232575641008,"x":4.7},{"cos":0.08749898343944727,"sin":-0.9961646088358406,"x":4.800000000000001},{"cos":0.18651236942257576,"sin":-0.9824526126243325,"x":4.9},{"cos":0.28366218546322625,"sin":-0.9589242746631385,"x":5.0},{"cos":0.37797774271298107,"sin":-0.9258146823277321,"x":5.1000000000000005},{"cos":0.4685166713003771,"sin":-0.8834546557201531,"x":5.2},{"cos":0.5543743361791615,"sin":-0.8322674422239008,"x":5.300000000000001},{"cos":0.6346928759426347,"sin":-0.7727644875559871,"x":5.4},{"cos":0.70866977429126,"sin":-0.7055403255703919,"x":5.5},{"cos":0.7755658785102502,"sin":-0.631266637872321,"x":5.6000000000000005},{"cos":0.8347127848391598,"sin":-0.5506855425976376,"x":5.7},{"cos":0.8855195169413194,"sin":-0.4646021794137566,"x":5.800000000000001},{"cos":0.9274784307440359,"sin":-0.373876664830236,"x":5.9},{"cos":0.960170286650366,"sin":-0.27941549819892586,"x":6.0},{"cos":0.9832684384425847,"sin":-0.18216250427209502,"x":6.1000000000000005},{"cos":0.9965420970232175,"sin":-0.0830894028174964,"x":6.2},{"cos":0.9998586363834151,"sin":0.0168139004843506,"x":6.300000000000001},{"cos":0.9931849187581926,"sin":0.11654920485049364,"x":6.4},{"cos":0.9765876257280235,"sin":0.21511998808781552,"x":6.5},{"cos":0.9502325919585293,"sin":0.3115413635133787,"x":6.6000000000000005},{"cos":0.9143831482353194,"sin":0.4048499206165983,"x":6.7},{"cos":0.8693974903498248,"sin":0.49411335113860894,"x":6.800000000000001},{"cos":0.8157251001253569,"sin":0.5784397643882002,"x":6.9},{"cos":0.7539022543433046,"sin":0.6569865987187891,"x":7.0},{"cos":0.6845466664428059,"sin":0.7289690401258765,"x":7.1000000000000005},{"cos":0.6083513145322546,"sin":0.7936678638491531,"x":7.2},{"cos":0.5260775173811045,"sin":0.850436620628565,"x":7.300000000000001},{"cos":0.43854732757439036,"sin":0.8987080958116269,"x":7.4},{"cos":0.3466353178350258,"sin":0.9379999767747389,"x":7.5},{"cos":0.25125984258225487,"sin":0.9679196720314865,"x":7.6000000000000005},{"cos":0.15337386203786435,"sin":0.9881682338770004,"x":7.7},{"cos":0.05395542056264886,"sin":0.998543345374605,"x":7.800000000000001},{"cos":-0.04600212563953695,"sin":0.998941341839772,"x":7.9},{"cos":-0.14550003380861354,"sin":0.9893582466233818,"x":8.0},{"cos":-0.2435441537357911,"sin":0.9698898108450863,"x":8.1},{"cos":-0.33915486098383624,"sin":0.9407305566797726,"x":8.200000000000001},{"cos":-0.43137684497062084,"sin":0.9021718337562934,"x":8.3},{"cos":-0.5192886541166856,"sin":0.8545989080882804,"x":8.4},{"cos":-0.6020119026848236,"sin":0.7984871126234903,"x":8.5},{"cos":-0.6787200473200125,"sin":0.7343970978741134,"x":8.6},{"cos":-0.7486466455973999,"sin":0.662969230082182,"x":8.700000000000001},{"cos":-0.811093014061656,"sin":0.5849171928917617,"x":8.8},{"cos":-0.8654352092411123,"sin":0.5010208564578846,"x":8.9},{"cos":-0.9111302618846769,"sin":0.4121184852417566,"x":9.0},{"cos":-0.9477216021311119,"sin":0.3190983623493521,"x":9.1},{"cos":-0.974843621404164,"sin":0.22288991410024592,"x":9.200000000000001},{"cos":-0.9922253254526034,"sin":0.1244544235070617,"x":9.3},{"cos":-0.9996930420352065,"sin":0.024775425453357765,"x":9.4},{"cos":-0.9971721561963784,"sin":-0.0751511204618093,"x":9.5},{"cos":-0.9846878557941267,"sin":-0.1743267812229814,"x":9.600000000000001},{"cos":-0.9623648798313097,"sin":-0.2717606264109442,"x":9.700000000000001},{"cos":-0.9304262721047533,"sin":-0.36647912925192844,"x":9.8},{"cos":-0.8891911526253609,"sin":-0.4575358937753214,"x":9.9},{"cos":-0.8390715290764524,"sin":-0.5440211108893698,"x":10.0}]},"encoding":{"x":{"field":"x","type":"quantitative"},"y":{"field":"sin","type":"quantitative"}},"mark":{"color":"green","fillOpacity":1,"strokeDash":[5,3,2],"strokeWidth":2,"type":"line"}}],"width":300}

You can use various interpolation methods. Some examples follow:

plots =
  for interpolation <- ["linear", "step", "cardinal", "monotone"] do
    Tucan.lineplot(:stocks, "date", "price",
      x: [type: :temporal, time_unit: :year],
      y: [aggregate: :mean],
      color_by: "symbol",
      interpolate: interpolation
    )
    |> Tucan.set_title(interpolation)
  end

Tucan.concat(plots, columns: 2)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","columns":2,"concat":[{"data":{"url":"https://vega.github.io/editor/data/stocks.csv"},"encoding":{"color":{"field":"symbol"},"x":{"field":"date","timeUnit":"year","type":"temporal"},"y":{"aggregate":"mean","field":"price","type":"quantitative"}},"mark":{"fillOpacity":1,"interpolate":"linear","type":"line"},"title":{"text":"linear"}},{"data":{"url":"https://vega.github.io/editor/data/stocks.csv"},"encoding":{"color":{"field":"symbol"},"x":{"field":"date","timeUnit":"year","type":"temporal"},"y":{"aggregate":"mean","field":"price","type":"quantitative"}},"mark":{"fillOpacity":1,"interpolate":"step","type":"line"},"title":{"text":"step"}},{"data":{"url":"https://vega.github.io/editor/data/stocks.csv"},"encoding":{"color":{"field":"symbol"},"x":{"field":"date","timeUnit":"year","type":"temporal"},"y":{"aggregate":"mean","field":"price","type":"quantitative"}},"mark":{"fillOpacity":1,"interpolate":"cardinal","type":"line"},"title":{"text":"cardinal"}},{"data":{"url":"https://vega.github.io/editor/data/stocks.csv"},"encoding":{"color":{"field":"symbol"},"x":{"field":"date","timeUnit":"year","type":"temporal"},"y":{"aggregate":"mean","field":"price","type":"quantitative"}},"mark":{"fillOpacity":1,"interpolate":"monotone","type":"line"},"title":{"text":"monotone"}}]}
Link to this function

lollipop(plotdata, field, value, opts \\ [])

View Source
@spec lollipop(
  plotdata :: plotdata(),
  field :: String.t(),
  value :: String.t(),
  opts :: keyword()
) :: VegaLite.t()

Draws a lollipop plot.

A lollipop plot is nothing more than a bar plot, where the bar is transformed in a line and a dot. It shows the relationship between a numeric and a categoric variable.

Comparison to bar/4

The lollipop plot is used exactly in the same situation as a bar plot. However it is somewhat more appealing and convey as well the information. It is especially useful when you have several bars of the same height.

data = [
  category: ["A", "B", "C", "D", "E"],
  value: [99, 97, 94, 90, 88]
]

bar = Tucan.bar(data, "category", "value", orient: :horizontal)
lollipop = Tucan.lollipop(data, "category", "value", orient: :horizontal)

Tucan.hconcat([bar, lollipop])
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","hconcat":[{"data":{"values":[{"category":"A","value":99},{"category":"B","value":97},{"category":"C","value":94},{"category":"D","value":90},{"category":"E","value":88}]},"encoding":{"x":{"field":"value","type":"quantitative"},"y":{"axis":{"labelAngle":0},"field":"category","type":"nominal"}},"mark":{"fillOpacity":1,"type":"bar"}},{"__tucan__":{"multilayer":true},"data":{"values":[{"category":"A","value":99},{"category":"B","value":97},{"category":"C","value":94},{"category":"D","value":90},{"category":"E","value":88}]},"layer":[{"encoding":{"x":{"field":"value","type":"quantitative"},"y":{"axis":{"labelAngle":0},"field":"category","type":"nominal"}},"mark":{"color":"black","type":"rule"}},{"encoding":{"x":{"field":"value","type":"quantitative"},"y":{"axis":{"labelAngle":0},"field":"category","type":"nominal"}},"mark":{"color":"black","filled":true,"opacity":1,"size":60,"type":"point"}}]}]}

See also bar/4.

Options

Data Grouping Options

  • :color_by (String.t/0) - If set a data field that will be used for coloring the data. It is considered :nominal by default.
  • :group_by (String.t/0) - A categorical field to group the lollipops by. It is used for adding a second dimension to the plot. When set, the groups are also color coded by the same categorical variable.

Data Options

  • :only - A subset of fields to pick from the data. Applicable only if tabular data are provided.

Styling Options

  • :height (pos_integer/0 or :container) - Height of the plot. Can either be the height in pixels or :container to indicate that the height of the plot should be the same as its surrounding container.
  • :line_color (String.t/0) - The color of the line The default value is "black".
  • :orient (atom/0) - The plot's orientation, can be either :horizontal or :vertical. The default value is :vertical.
  • :point_color (String.t/0) - The color of the points The default value is "black".
  • :point_shape - Shape of the point marks. Circle by default.
  • :point_size (pos_integer/0) - The pixel area of the marks. Note that this value sets the area of the symbol; the side lengths will increase with the square root of this value. The default value is 60.
  • :title (String.t/0) - The title of the graph
  • :width (pos_integer/0 or :container) - Width of the plot. Can either be the width in pixels or :container to indicate that the width of the plot should be the same as its surrounding container.

Encodings Custom Options

All Tucan plots are building a VegaLite specification based on some sane default parameters. Through these encodings options you are free to set any vega-lite supported option to any encoding channel of the plot.

Notice that if set they will be merged with any option set by the plot. Since they have a higher precedence they may override the default settings and affect the generated plot.

You can set an arbitrary keyword list. Notice that the contents are not validated.

  • :color (keyword/0) - Extra vega lite options for the :color encoding. The default value is [].
  • :x (keyword/0) - Extra vega lite options for the :x encoding. The default value is [].
  • :x_offset (keyword/0) - Extra vega lite options for the :x_offset encoding. The default value is [].
  • :y (keyword/0) - Extra vega lite options for the :y encoding. The default value is [].
  • :y_offset (keyword/0) - Extra vega lite options for the :y_offset encoding. The default value is [].

Interactivity Options

  • :tooltip (boolean() | :data | :encoding) - The tooltip text string to show upon mouse hover or an object defining which fields should the tooltip be derived from. Can be one of the following:

    • :encoding - all fields from encoding are used
    • :data - all fields of the highlighted data point are used
    • true - same as :encoding
    • false, nil - no tooltip is used

Examples

A lollipop chart for some synthetic data:

data =
  for category <- ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J"] do
    %{category: category, value: 9 + :rand.uniform(90)}
  end

Tucan.lollipop(data, "category", "value", width: 400)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","__tucan__":{"multilayer":true},"data":{"values":[{"category":"A","value":37},{"category":"B","value":31},{"category":"C","value":42},{"category":"D","value":23},{"category":"E","value":65},{"category":"F","value":41},{"category":"G","value":16},{"category":"H","value":44},{"category":"I","value":50},{"category":"J","value":74}]},"layer":[{"encoding":{"x":{"axis":{"labelAngle":0},"field":"category","type":"nominal"},"y":{"field":"value","type":"quantitative"}},"mark":{"color":"black","type":"rule"}},{"encoding":{"x":{"axis":{"labelAngle":0},"field":"category","type":"nominal"},"y":{"field":"value","type":"quantitative"}},"mark":{"color":"black","filled":true,"opacity":1,"size":60,"type":"point"}}],"width":400}

You can make the lollipops horizontal by setting the :orient flag:

data =
  for category <- ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J"] do
    %{category: category, value: 9 + :rand.uniform(90)}
  end

Tucan.lollipop(data, "category", "value", width: 400, orient: :horizontal)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","__tucan__":{"multilayer":true},"data":{"values":[{"category":"A","value":91},{"category":"B","value":79},{"category":"C","value":83},{"category":"D","value":90},{"category":"E","value":27},{"category":"F","value":47},{"category":"G","value":69},{"category":"H","value":27},{"category":"I","value":12},{"category":"J","value":13}]},"layer":[{"encoding":{"x":{"field":"value","type":"quantitative"},"y":{"axis":{"labelAngle":0},"field":"category","type":"nominal"}},"mark":{"color":"black","type":"rule"}},{"encoding":{"x":{"field":"value","type":"quantitative"},"y":{"axis":{"labelAngle":0},"field":"category","type":"nominal"}},"mark":{"color":"black","filled":true,"opacity":1,"size":60,"type":"point"}}],"width":400}

You can change the points shape and the default colors if needed:

data =
  for category <- ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J"] do
    %{category: category, value: 9 + :rand.uniform(90)}
  end

Tucan.lollipop(data, "category", "value",
  point_color: "red",
  point_shape: "square",
  point_size: 80,
  line_color: "blue",
  width: 400
)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","__tucan__":{"multilayer":true},"data":{"values":[{"category":"A","value":94},{"category":"B","value":80},{"category":"C","value":50},{"category":"D","value":40},{"category":"E","value":40},{"category":"F","value":35},{"category":"G","value":67},{"category":"H","value":59},{"category":"I","value":28},{"category":"J","value":67}]},"layer":[{"encoding":{"x":{"axis":{"labelAngle":0},"field":"category","type":"nominal"},"y":{"field":"value","type":"quantitative"}},"mark":{"color":"blue","type":"rule"}},{"encoding":{"x":{"axis":{"labelAngle":0},"field":"category","type":"nominal"},"y":{"field":"value","type":"quantitative"}},"mark":{"color":"red","filled":true,"opacity":1,"shape":"square","size":80,"type":"point"}}],"width":400}

If you need to group by a second categorical variable you can use the :group_by option:

data =
  for category <- ["A", "B", "C", "D", "E", "F", "G"],
      country <- ["US", "GR", "UK", "IT"] do
    %{category: category, country: country, value: 9 + :rand.uniform(90)}
  end

Tucan.lollipop(data, "category", "value", group_by: "country", orient: :horizontal)
|> Tucan.set_size(400, 300)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","__tucan__":{"multilayer":true},"data":{"values":[{"category":"A","country":"US","value":22},{"category":"A","country":"GR","value":66},{"category":"A","country":"UK","value":66},{"category":"A","country":"IT","value":34},{"category":"B","country":"US","value":68},{"category":"B","country":"GR","value":84},{"category":"B","country":"UK","value":94},{"category":"B","country":"IT","value":88},{"category":"C","country":"US","value":84},{"category":"C","country":"GR","value":56},{"category":"C","country":"UK","value":32},{"category":"C","country":"IT","value":12},{"category":"D","country":"US","value":98},{"category":"D","country":"GR","value":82},{"category":"D","country":"UK","value":84},{"category":"D","country":"IT","value":24},{"category":"E","country":"US","value":76},{"category":"E","country":"GR","value":20},{"category":"E","country":"UK","value":12},{"category":"E","country":"IT","value":92},{"category":"F","country":"US","value":36},{"category":"F","country":"GR","value":90},{"category":"F","country":"UK","value":77},{"category":"F","country":"IT","value":62},{"category":"G","country":"US","value":18},{"category":"G","country":"GR","value":57},{"category":"G","country":"UK","value":16},{"category":"G","country":"IT","value":50}]},"height":300,"layer":[{"encoding":{"color":{"field":"country","type":"nominal"},"x":{"field":"value","type":"quantitative"},"y":{"axis":{"labelAngle":0},"field":"category","type":"nominal"},"yOffset":{"field":"country","type":"nominal"}},"mark":{"color":"black","type":"rule"}},{"encoding":{"color":{"field":"country","type":"nominal"},"x":{"field":"value","type":"quantitative"},"y":{"axis":{"labelAngle":0},"field":"category","type":"nominal"},"yOffset":{"field":"country","type":"nominal"}},"mark":{"color":"black","filled":true,"opacity":1,"size":60,"type":"point"}}],"width":400}
Link to this function

pie(plotdata, field, category, opts \\ [])

View Source
@spec pie(
  plotdata :: plotdata(),
  field :: String.t(),
  category :: String.t(),
  opts :: keyword()
) :: VegaLite.t()

Draws a pie chart.

A pie chart is a circle divided into sectors that each represents a proportion of the whole. The field specifies the data column that contains the proportions of each category. The chart will be colored by the category field.

Avoid using pie charts

Despite it's popularity pie charts should rarely be used. Pie charts are best suited for displaying a small number of categories and can make it challenging to accurately compare data. They rely on angle perception, which can lead to misinterpretation, and lack the precision offered by other charts like bar charts or line charts.

Instead, opt for alternatives such as bar charts for straightforward comparisons, stacked area charts for cumulative effects.

The following example showcases the limitations of a pie chart, compared to a bar chart:

alias VegaLite, as: Vl

data = [
  %{value: 30, category: "A"},
  %{value: 33, category: "B"},
  %{value: 38, category: "C"}
]

pie = Tucan.pie(data, "value", "category")
bar = Tucan.bar(data, "category", "value", orient: :horizontal)

Tucan.hconcat([pie, bar])
|> Tucan.set_title("Pie vs Bar chart", anchor: :middle, offset: 15)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","hconcat":[{"data":{"values":[{"category":"A","value":30},{"category":"B","value":33},{"category":"C","value":38}]},"encoding":{"color":{"field":"category"},"theta":{"field":"value","type":"quantitative"}},"mark":{"fillOpacity":1,"type":"arc"}},{"data":{"values":[{"category":"A","value":30},{"category":"B","value":33},{"category":"C","value":38}]},"encoding":{"x":{"field":"value","type":"quantitative"},"y":{"axis":{"labelAngle":0},"field":"category","type":"nominal"}},"mark":{"fillOpacity":1,"type":"bar"}}],"title":{"anchor":"middle","offset":15,"text":"Pie vs Bar chart"}}

Options

  • :aggregate (atom/0) - The statistic to use (if any) for aggregating values per pie slice (e.g. :mean).
  • :inner_radius (integer/0) - The inner radius in pixels. 0 for a pie chart, > 0 for a donut chart. If not set it defaults to 0

Data Options

  • :only - A subset of fields to pick from the data. Applicable only if tabular data are provided.

Styling Options

  • :clip (boolean/0) - Whether a mark will be clipped to the enclosing group’s width and height.
  • :fill_opacity (number/0) - The fill opacity of the plotted elements. The default value is 1.
  • :height (pos_integer/0 or :container) - Height of the plot. Can either be the height in pixels or :container to indicate that the height of the plot should be the same as its surrounding container.
  • :title (String.t/0) - The title of the graph
  • :width (pos_integer/0 or :container) - Width of the plot. Can either be the width in pixels or :container to indicate that the width of the plot should be the same as its surrounding container.

Encodings Custom Options

All Tucan plots are building a VegaLite specification based on some sane default parameters. Through these encodings options you are free to set any vega-lite supported option to any encoding channel of the plot.

Notice that if set they will be merged with any option set by the plot. Since they have a higher precedence they may override the default settings and affect the generated plot.

You can set an arbitrary keyword list. Notice that the contents are not validated.

  • :color (keyword/0) - Extra vega lite options for the :color encoding. The default value is [].
  • :theta (keyword/0) - Extra vega lite options for the :theta encoding. The default value is [].

Interactivity Options

  • :tooltip (boolean() | :data | :encoding) - The tooltip text string to show upon mouse hover or an object defining which fields should the tooltip be derived from. Can be one of the following:

    • :encoding - all fields from encoding are used
    • :data - all fields of the highlighted data point are used
    • true - same as :encoding
    • false, nil - no tooltip is used

Examples

Tucan.pie(:barley, "yield", "site", aggregate: :sum, tooltip: true)
|> Tucan.facet_by(:column, "year", type: :nominal)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://vega.github.io/editor/data/barley.json"},"encoding":{"color":{"field":"site"},"column":{"field":"year","type":"nominal"},"theta":{"aggregate":"sum","field":"yield","type":"quantitative"}},"mark":{"fillOpacity":1,"tooltip":true,"type":"arc"}}
Link to this function

punchcard(plotdata, x, y, size, opts \\ [])

View Source
@spec punchcard(
  plotdata :: plotdata(),
  x :: String.t(),
  y :: String.t(),
  size :: nil | String.t(),
  opts :: keyword()
) :: VegaLite.t()

Returns the specification of a punch card plot.

A punch card plot is similar to a heatmap but instead of color the third dimension is encoded by the size of bubbles.

See also heatmap/5.

Options

  • :aggregate (atom/0) - The statistic that will be used for aggregating the observations within a heatmap tile. Defaults to :mean which in case of single data will encode the value of the color data field.

    Ignored if :color is set to nil.

  • :annotate (boolean/0) - If set to true then the values of each cell will be included in the plot. The default value is false.

Data Options

  • :only - A subset of fields to pick from the data. Applicable only if tabular data are provided.

Styling Options

  • :clip (boolean/0) - Whether a mark will be clipped to the enclosing group’s width and height.
  • :color_scheme (atom/0) - The color scheme to use, for supported color schemes check Tucan.Scale. Notice that this is just a helper option for easily setting color schemes. If you need to set specific colors or customize the scheme, use Tucan.Scale.set_color_scheme/3.
  • :fill_opacity (number/0) - The fill opacity of the plotted elements. The default value is 1.
  • :height (pos_integer/0 or :container) - Height of the plot. Can either be the height in pixels or :container to indicate that the height of the plot should be the same as its surrounding container.
  • :text_color - The color to be used for the textual annotations. Valid only if :annotate is set to true. Can be one of the following:
    • a string with the color to be used, e.g. "white"
    • a list of tuples of the form {low_threshold, upper_threshold, color} for conditionally setting the color based on the value of the annotated variable. low_threshold and upper_threshold can either be a number or nil. For example [{nil, 0, "green"}, {0, 5, "red"}, {5, nil, "white"}] will apply the following colors:
      • green for all items with value < 0
      • red for all items with value >= 0 && value < 5
      • white for all items with value >= 5 Notice that the low_threshold, upper_threshold correspond to the [low_threshold, upper_threshold) range.
  • :title (String.t/0) - The title of the graph
  • :width (pos_integer/0 or :container) - Width of the plot. Can either be the width in pixels or :container to indicate that the width of the plot should be the same as its surrounding container.

Encodings Custom Options

All Tucan plots are building a VegaLite specification based on some sane default parameters. Through these encodings options you are free to set any vega-lite supported option to any encoding channel of the plot.

Notice that if set they will be merged with any option set by the plot. Since they have a higher precedence they may override the default settings and affect the generated plot.

You can set an arbitrary keyword list. Notice that the contents are not validated.

  • :size (keyword/0) - Extra vega lite options for the :size encoding. The default value is [].
  • :x (keyword/0) - Extra vega lite options for the :x encoding. The default value is [].
  • :y (keyword/0) - Extra vega lite options for the :y encoding. The default value is [].

Interactivity Options

  • :tooltip (boolean() | :data | :encoding) - The tooltip text string to show upon mouse hover or an object defining which fields should the tooltip be derived from. Can be one of the following:

    • :encoding - all fields from encoding are used
    • :data - all fields of the highlighted data point are used
    • true - same as :encoding
    • false, nil - no tooltip is used

Examples

Tucan.punchcard(:weather, "date", "date", "temp_max",
  tooltip: true,
  x: [type: :ordinal, time_unit: :date],
  y: [type: :ordinal, time_unit: :month]
)
|> Tucan.Axes.set_x_title("Day")
|> Tucan.Axes.set_y_title("Month")
|> Tucan.set_title("Punch card of Avg Max Temperatures in Seattle (2012-2015)")
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","__tucan__":{"multilayer":true},"data":{"url":"https://vega.github.io/editor/data/weather.csv"},"layer":[{"encoding":{"size":{"aggregate":"mean","field":"temp_max","type":"quantitative"},"x":{"axis":{"title":"Day"},"field":"date","timeUnit":"date","type":"ordinal"},"y":{"axis":{"title":"Month"},"field":"date","timeUnit":"month","type":"ordinal"}},"mark":{"fillOpacity":1,"tooltip":true,"type":"circle"}}],"title":{"text":"Punch card of Avg Max Temperatures in Seattle (2012-2015)"}}

You can add a fourth dimension by coloring the plot by a fourth variable. Notice how we use Tucan.Scale.set_color_scheme/3 to apply a semantically reasonable coloring and Tucan.Legend.set_orientation/3 to change the default position of the two legends.

Tucan.punchcard(:weather, "date", "date", "precipitation",
  tooltip: true,
  x: [type: :ordinal, time_unit: :date],
  y: [type: :ordinal, time_unit: :month]
)
# we need to set recursive to true since this is a layered plot
|> Tucan.color_by("temp_max", aggregate: :mean, recursive: true)
|> Tucan.Scale.set_color_scheme(:redyellowblue, reverse: true)
|> Tucan.Axes.set_x_title("Day")
|> Tucan.Axes.set_y_title("Month")
|> Tucan.Legend.set_orientation(:color, "bottom")
|> Tucan.Legend.set_orientation(:size, "bottom")
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","__tucan__":{"multilayer":true},"data":{"url":"https://vega.github.io/editor/data/weather.csv"},"layer":[{"encoding":{"color":{"aggregate":"mean","field":"temp_max","legend":{"orient":"bottom"},"scale":{"reverse":true,"scheme":"redyellowblue"}},"size":{"aggregate":"mean","field":"precipitation","legend":{"orient":"bottom"},"type":"quantitative"},"x":{"axis":{"title":"Day"},"field":"date","timeUnit":"date","type":"ordinal"},"y":{"axis":{"title":"Month"},"field":"date","timeUnit":"month","type":"ordinal"}},"mark":{"fillOpacity":1,"tooltip":true,"type":"circle"}}]}
Link to this function

range_bar(plotdata, field, min, max, opts \\ [])

View Source
@spec range_bar(
  plotdata :: plotdata(),
  field :: String.t(),
  min :: String.t(),
  max :: String.t(),
  opts :: keyword()
) :: VegaLite.t()

Draws a range bar chart.

A range bar chart is a bar chart where the bar is not a single value, but a range defined by a min and max value. It is used for showing intervals or ranges of data.

Options

Data Grouping Options

  • :color_by (String.t/0) - If set a data field that will be used for coloring the data. It is considered :nominal by default.

Data Options

  • :only - A subset of fields to pick from the data. Applicable only if tabular data are provided.

Styling Options

  • :clip (boolean/0) - Whether a mark will be clipped to the enclosing group’s width and height.
  • :corner_radius (non_neg_integer/0) - The radius in pixels of rounded rectangles. The end radius is affected:
    • For vertical bars, top-left and top-right corner radius.
    • For horizontal bars, top-right and bottom-right corner radius.
  • :fill_color (String.t/0) - The fill color of the marks. This will override the color encoding if set.
  • :fill_opacity (number/0) - The fill opacity of the plotted elements. The default value is 1.
  • :height (pos_integer/0 or :container) - Height of the plot. Can either be the height in pixels or :container to indicate that the height of the plot should be the same as its surrounding container.
  • :orient (atom/0) - The plot's orientation, can be either :horizontal or :vertical. The default value is :horizontal.
  • :title (String.t/0) - The title of the graph
  • :width (pos_integer/0 or :container) - Width of the plot. Can either be the width in pixels or :container to indicate that the width of the plot should be the same as its surrounding container.

Encodings Custom Options

All Tucan plots are building a VegaLite specification based on some sane default parameters. Through these encodings options you are free to set any vega-lite supported option to any encoding channel of the plot.

Notice that if set they will be merged with any option set by the plot. Since they have a higher precedence they may override the default settings and affect the generated plot.

You can set an arbitrary keyword list. Notice that the contents are not validated.

  • :color (keyword/0) - Extra vega lite options for the :color encoding. The default value is [].
  • :x (keyword/0) - Extra vega lite options for the :x encoding. The default value is [].
  • :x2 (keyword/0) - Extra vega lite options for the :x2 encoding. The default value is [].
  • :x_offset (keyword/0) - Extra vega lite options for the :x_offset encoding. The default value is [].
  • :y (keyword/0) - Extra vega lite options for the :y encoding. The default value is [].
  • :y2 (keyword/0) - Extra vega lite options for the :y2 encoding. The default value is [].
  • :y_offset (keyword/0) - Extra vega lite options for the :y_offset encoding. The default value is [].

Interactivity Options

  • :tooltip (boolean() | :data | :encoding) - The tooltip text string to show upon mouse hover or an object defining which fields should the tooltip be derived from. Can be one of the following:

    • :encoding - all fields from encoding are used
    • :data - all fields of the highlighted data point are used
    • true - same as :encoding
    • false, nil - no tooltip is used
  • :zoomable (boolean/0) - Whether the plot will be zoomable or not. If set to true you will be able to pan and zoom the plot with your mouse. You can reset to the original view with a double click. The default value is false.

Examples

A simple ranged bar chart:

data = [
  %{"id" => "A", "min" => 28, "max" => 55},
  %{"id" => "B", "min" => 43, "max" => 91},
  %{"id" => "C", "min" => 13, "max" => 61}
]

Tucan.range_bar(data, "id", "min", "max")
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"values":[{"id":"A","max":55,"min":28},{"id":"B","max":91,"min":43},{"id":"C","max":61,"min":13}]},"encoding":{"x":{"field":"min","type":"quantitative"},"x2":{"field":"max","type":"quantitative"},"y":{"axis":{"labelAngle":0},"field":"id","type":"nominal"}},"mark":{"fillOpacity":1,"type":"bar"}}

You can set a color_by option that will create a stacked ranged bar chart:

data = [
  %{"product" => "Laptop", "category" => "Basic", "min_price" => 499, "max_price" => 799},
  %{"product" => "Laptop", "category" => "Regular", "min_price" => 999, "max_price" => 1799},
  %{"product" => "Laptop", "category" => "Premium", "min_price" => 1499, "max_price" => 2499},
  %{"product" => "Smartphone", "category" => "Basic", "min_price" => 199, "max_price" => 399},
  %{"product" => "Smartphone", "category" => "Regular", "min_price" => 399, "max_price" => 699},
  %{"product" => "Smartphone", "category" => "Premium", "min_price" => 699, "max_price" => 1299},
  %{"product" => "Tablet", "category" => "Basic", "min_price" => 299, "max_price" => 499},
  %{"product" => "Tablet", "category" => "Regular", "min_price" => 399, "max_price" => 699},
  %{"product" => "Tablet", "category" => "Premium", "min_price" => 599, "max_price" => 1990}
]

Tucan.range_bar(data, "product", "min_price", "max_price",
  color_by: "category",
  tooltip: true
)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"values":[{"category":"Basic","max_price":799,"min_price":499,"product":"Laptop"},{"category":"Regular","max_price":1799,"min_price":999,"product":"Laptop"},{"category":"Premium","max_price":2499,"min_price":1499,"product":"Laptop"},{"category":"Basic","max_price":399,"min_price":199,"product":"Smartphone"},{"category":"Regular","max_price":699,"min_price":399,"product":"Smartphone"},{"category":"Premium","max_price":1299,"min_price":699,"product":"Smartphone"},{"category":"Basic","max_price":499,"min_price":299,"product":"Tablet"},{"category":"Regular","max_price":699,"min_price":399,"product":"Tablet"},{"category":"Premium","max_price":1990,"min_price":599,"product":"Tablet"}]},"encoding":{"color":{"field":"category"},"x":{"field":"min_price","type":"quantitative"},"x2":{"field":"max_price","type":"quantitative"},"y":{"axis":{"labelAngle":0},"field":"product","type":"nominal"},"yOffset":{"field":"category"}},"mark":{"fillOpacity":1,"tooltip":true,"type":"bar"}}

You can tweak the look of the chart using the supported options:

data = [
  %{"id" => "A", "min" => 28, "max" => 55},
  %{"id" => "B", "min" => 43, "max" => 91},
  %{"id" => "C", "min" => 13, "max" => 61}
]

Tucan.range_bar(data, "id", "min", "max",
  orient: :vertical,
  fill_color: "#33245A",
  corner_radius: 5
)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"values":[{"id":"A","max":55,"min":28},{"id":"B","max":91,"min":43},{"id":"C","max":61,"min":13}]},"encoding":{"x":{"axis":{"labelAngle":0},"field":"id","type":"nominal"},"y":{"field":"min","type":"quantitative"},"y2":{"field":"max","type":"quantitative"}},"mark":{"color":"#33245A","cornerRadiusEnd":5,"fillOpacity":1,"type":"bar"}}
Link to this function

scatter(plotdata, x, y, opts \\ [])

View Source
@spec scatter(
  plotdata :: plotdata(),
  x :: String.t(),
  y :: String.t(),
  opts :: keyword()
) ::
  VegaLite.t()

Returns the specification of a scatter plot with possibility of several semantic groupings.

Both x and y must be :quantitative.

Semantic groupings

The relationship between x and y can be shown for different subsets of the data using the color_by, size_by and shape_by parameters. This is equivalent to calling the corresponding functions after a scatter/4 call.

These parameters control what visual semantics are used to identify the different subsets. It is possible to show up to three dimensions independently by using all three semantic types, but this style of plot can be hard to interpret and is often ineffective.

Tucan.scatter(:tips, "total_bill", "tip",
  color_by: "day",
  shape_by: "sex",
  size_by: "size"
)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://raw.githubusercontent.com/mwaskom/seaborn-data/master/tips.csv"},"encoding":{"color":{"field":"day","type":"nominal"},"shape":{"field":"sex","type":"nominal"},"size":{"field":"size","type":"quantitative"},"x":{"field":"total_bill","scale":{"zero":false},"type":"quantitative"},"y":{"field":"tip","scale":{"zero":false},"type":"quantitative"}},"mark":{"fillOpacity":1,"type":"point"}}

The above is equivalent to calling:

Tucan.scatter(:tips, "total_bill", "tip")
|> Tucan.color_by("day", type: :nominal)
|> Tucan.shape_by("sex", type: :nominal)
|> Tucan.size_by("size", type: :quantitative)

Using redundant semantics (i.e. both color and shape for the same variable) can be helpful for making graphics more accessible.

Tucan.scatter(:tips, "total_bill", "tip",
  color_by: "day",
  shape_by: "day"
)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://raw.githubusercontent.com/mwaskom/seaborn-data/master/tips.csv"},"encoding":{"color":{"field":"day","type":"nominal"},"shape":{"field":"day","type":"nominal"},"x":{"field":"total_bill","scale":{"zero":false},"type":"quantitative"},"y":{"field":"tip","scale":{"zero":false},"type":"quantitative"}},"mark":{"fillOpacity":1,"type":"point"}}

Options

Data Grouping Options

  • :color_by (String.t/0) - If set a data field that will be used for coloring the data. It is considered :nominal by default.
  • :shape_by (String.t/0) - If set a data field that will be used for setting the shape of the data points. It is considered :nominal by default.
  • :size_by (String.t/0) - If set a data field that will be used for controlling the size of the data points. It is considered :quantitative by default.

Data Options

  • :only - A subset of fields to pick from the data. Applicable only if tabular data are provided.

Styling Options

  • :clip (boolean/0) - Whether a mark will be clipped to the enclosing group’s width and height.
  • :fill_opacity (number/0) - The fill opacity of the plotted elements. The default value is 1.
  • :filled (boolean/0) - Whether the mark will be filled or not
  • :height (pos_integer/0 or :container) - Height of the plot. Can either be the height in pixels or :container to indicate that the height of the plot should be the same as its surrounding container.
  • :point_color (String.t/0) - The color of the points
  • :point_shape - Shape of the point marks. Circle by default.
  • :point_size (pos_integer/0) - The pixel area of the marks. Note that this value sets the area of the symbol; the side lengths will increase with the square root of this value.
  • :title (String.t/0) - The title of the graph
  • :width (pos_integer/0 or :container) - Width of the plot. Can either be the width in pixels or :container to indicate that the width of the plot should be the same as its surrounding container.

Encodings Custom Options

All Tucan plots are building a VegaLite specification based on some sane default parameters. Through these encodings options you are free to set any vega-lite supported option to any encoding channel of the plot.

Notice that if set they will be merged with any option set by the plot. Since they have a higher precedence they may override the default settings and affect the generated plot.

You can set an arbitrary keyword list. Notice that the contents are not validated.

  • :color (keyword/0) - Extra vega lite options for the :color encoding. The default value is [].
  • :shape (keyword/0) - Extra vega lite options for the :shape encoding. The default value is [].
  • :size (keyword/0) - Extra vega lite options for the :size encoding. The default value is [].
  • :x (keyword/0) - Extra vega lite options for the :x encoding. The default value is [].
  • :y (keyword/0) - Extra vega lite options for the :y encoding. The default value is [].

Interactivity Options

  • :tooltip (boolean() | :data | :encoding) - The tooltip text string to show upon mouse hover or an object defining which fields should the tooltip be derived from. Can be one of the following:

    • :encoding - all fields from encoding are used
    • :data - all fields of the highlighted data point are used
    • true - same as :encoding
    • false, nil - no tooltip is used
  • :zoomable (boolean/0) - Whether the plot will be zoomable or not. If set to true you will be able to pan and zoom the plot with your mouse. You can reset to the original view with a double click. The default value is false.

Examples

We will use the :tips dataset throughout the following examples.

Drawing a scatter plot between two variables:

Tucan.scatter(:tips, "total_bill", "tip")
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://raw.githubusercontent.com/mwaskom/seaborn-data/master/tips.csv"},"encoding":{"x":{"field":"total_bill","scale":{"zero":false},"type":"quantitative"},"y":{"field":"tip","scale":{"zero":false},"type":"quantitative"}},"mark":{"fillOpacity":1,"type":"point"}}

You can modify the look of the plot by setting various styling options:

Tucan.scatter(:tips, "total_bill", "tip",
  point_color: "red",
  point_shape: "triangle-up",
  point_size: 10
)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://raw.githubusercontent.com/mwaskom/seaborn-data/master/tips.csv"},"encoding":{"x":{"field":"total_bill","scale":{"zero":false},"type":"quantitative"},"y":{"field":"tip","scale":{"zero":false},"type":"quantitative"}},"mark":{"color":"red","fillOpacity":1,"shape":"triangle-up","size":10,"type":"point"}}

You can combine it with color_by/3 to color code the points with respect to another variable:

Tucan.scatter(:tips, "total_bill", "tip")
|> Tucan.color_by("time")
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://raw.githubusercontent.com/mwaskom/seaborn-data/master/tips.csv"},"encoding":{"color":{"field":"time"},"x":{"field":"total_bill","scale":{"zero":false},"type":"quantitative"},"y":{"field":"tip","scale":{"zero":false},"type":"quantitative"}},"mark":{"fillOpacity":1,"type":"point"}}

Assigning the same variable to shape_by/3 will also vary the markers and create a more accessible plot:

Tucan.scatter(:tips, "total_bill", "tip", width: 400)
|> Tucan.color_by("time")
|> Tucan.shape_by("time")
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://raw.githubusercontent.com/mwaskom/seaborn-data/master/tips.csv"},"encoding":{"color":{"field":"time"},"shape":{"field":"time"},"x":{"field":"total_bill","scale":{"zero":false},"type":"quantitative"},"y":{"field":"tip","scale":{"zero":false},"type":"quantitative"}},"mark":{"fillOpacity":1,"type":"point"},"width":400}

Assigning color_by/3 and shape_by/3 to different variables will vary colors and markers independently:

Tucan.scatter(:tips, "total_bill", "tip", width: 400)
|> Tucan.color_by("day")
|> Tucan.shape_by("time")
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://raw.githubusercontent.com/mwaskom/seaborn-data/master/tips.csv"},"encoding":{"color":{"field":"day"},"shape":{"field":"time"},"x":{"field":"total_bill","scale":{"zero":false},"type":"quantitative"},"y":{"field":"tip","scale":{"zero":false},"type":"quantitative"}},"mark":{"fillOpacity":1,"type":"point"},"width":400}

You can also color the points by a numeric variable, the semantic mapping will be quantitative and will use a different default palette:

Tucan.scatter(:tips, "total_bill", "tip", width: 400)
|> Tucan.color_by("size", type: :quantitative)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://raw.githubusercontent.com/mwaskom/seaborn-data/master/tips.csv"},"encoding":{"color":{"field":"size","type":"quantitative"},"x":{"field":"total_bill","scale":{"zero":false},"type":"quantitative"},"y":{"field":"tip","scale":{"zero":false},"type":"quantitative"}},"mark":{"fillOpacity":1,"type":"point"},"width":400}

A numeric variable can also be assigned to size to apply a semantic mapping to the areas of the points:

Tucan.scatter(:tips, "total_bill", "tip", width: 400, tooltip: :data)
|> Tucan.color_by("size", type: :quantitative)
|> Tucan.size_by("size", type: :quantitative)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://raw.githubusercontent.com/mwaskom/seaborn-data/master/tips.csv"},"encoding":{"color":{"field":"size","type":"quantitative"},"size":{"field":"size","type":"quantitative"},"x":{"field":"total_bill","scale":{"zero":false},"type":"quantitative"},"y":{"field":"tip","scale":{"zero":false},"type":"quantitative"}},"mark":{"fillOpacity":1,"tooltip":{"content":"data"},"type":"point"},"width":400}

You can also combine it with facet_by/3 in order to group within additional categorical variables, and plot them across multiple subplots.

Tucan.scatter(:tips, "total_bill", "tip", width: 300)
|> Tucan.color_by("day")
|> Tucan.shape_by("day")
|> Tucan.facet_by(:column, "time")
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://raw.githubusercontent.com/mwaskom/seaborn-data/master/tips.csv"},"encoding":{"color":{"field":"day"},"column":{"field":"time"},"shape":{"field":"day"},"x":{"field":"total_bill","scale":{"zero":false},"type":"quantitative"},"y":{"field":"tip","scale":{"zero":false},"type":"quantitative"}},"mark":{"fillOpacity":1,"type":"point"},"width":300}

You can also apply faceting on more than one variables, both horizontally and vertically:

Tucan.scatter(:tips, "total_bill", "tip", width: 300)
|> Tucan.color_by("day")
|> Tucan.shape_by("day")
|> Tucan.size_by("size")
|> Tucan.facet_by(:column, "time")
|> Tucan.facet_by(:row, "sex")
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://raw.githubusercontent.com/mwaskom/seaborn-data/master/tips.csv"},"encoding":{"color":{"field":"day"},"column":{"field":"time"},"row":{"field":"sex"},"shape":{"field":"day"},"size":{"field":"size","type":"quantitative"},"x":{"field":"total_bill","scale":{"zero":false},"type":"quantitative"},"y":{"field":"tip","scale":{"zero":false},"type":"quantitative"}},"mark":{"fillOpacity":1,"type":"point"},"width":300}
Link to this function

step(plotdata, x, y, opts \\ [])

View Source
@spec step(plotdata :: plotdata(), x :: field(), y :: field(), opts :: keyword()) ::
  VegaLite.t()

Returns the specification of a step chart.

This is a simple wrapper around lineplot/4 with :interpolate set by default to "step". If :interpolate is set to any of step, step-before, step-after it will be used. In any other case defaults to step.

Options

Check lineplot/4

Examples

Tucan.step(:stocks, "date", "price", color_by: "symbol", width: 300, x: [type: :temporal])
|> Tucan.Scale.set_y_scale(:log)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://vega.github.io/editor/data/stocks.csv"},"encoding":{"color":{"field":"symbol"},"x":{"field":"date","type":"temporal"},"y":{"field":"price","scale":{"type":"log"},"type":"quantitative"}},"mark":{"fillOpacity":1,"interpolate":"step","type":"line"},"width":300}
Link to this function

streamgraph(plotdata, x, y, group, opts \\ [])

View Source
@spec streamgraph(
  plotdata :: plotdata(),
  x :: field(),
  y :: field(),
  group :: field(),
  opts :: keyword()
) :: VegaLite.t()

Returns the specification of a streamgraph.

This is a simple wrapper around area/4 with :mode set by default to :streamgraph. Any value set to the :mode option will be ignored.

A grouping field must also be provided which will be set as :color_by to the area chart.

Options

Check area/4

Examples

Tucan.streamgraph(:stocks, "date", "price", "symbol",
  width: 300,
  x: [type: :temporal],
  tooltip: true
)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://vega.github.io/editor/data/stocks.csv"},"encoding":{"color":{"field":"symbol"},"x":{"field":"date","type":"temporal"},"y":{"field":"price","stack":"center","type":"quantitative"}},"mark":{"fillOpacity":1,"line":false,"tooltip":true,"type":"area"},"width":300}
Link to this function

stripplot(plotdata, field, opts \\ [])

View Source
@spec stripplot(plotdata :: plotdata(), field :: String.t(), opts :: keyword()) ::
  VegaLite.t()

Draws a strip plot (categorical scatterplot).

A strip plot is a single-axis scatter plot used to visualize the distribution of a numerical field. The values are plotted as dots or ticks along one axis, so the dots with the same value may overlap.

You can use the :jitter mode for a better view of overlapping points. In this case points are randomly shifted along with other axis, which has no meaning in itself data-wise.

Typically several strip plots are placed side by side to compare the distribution of a numerical value among several categories.

Options

  • :group_by (String.t/0) - A field to be used for grouping the strip plot. If not set the plot will be one dimensional.

  • :jitter_mode - The distribution from which the jitter (random offset) will be generated. One of :uniform, :normal. Applicable only when the :style is set to :jitter. The default value is :normal.

  • :style - The style of the plot. Can be one of the following:

    • :tick - use ticks for each data point
    • :point - use points for each data point
    • :jitter - use points but also apply some jittering across the other axis

    Use :jitter in case of many data points in order to avoid overlaps.

    The default value is :tick.

Data Grouping Options

  • :color_by (String.t/0) - If set a data field that will be used for coloring the data. It is considered :nominal by default.

Data Options

  • :only - A subset of fields to pick from the data. Applicable only if tabular data are provided.

Styling Options

  • :clip (boolean/0) - Whether a mark will be clipped to the enclosing group’s width and height.
  • :fill_opacity (number/0) - The fill opacity of the plotted elements. The default value is 1.
  • :height (pos_integer/0 or :container) - Height of the plot. Can either be the height in pixels or :container to indicate that the height of the plot should be the same as its surrounding container.
  • :orient (atom/0) - The plot's orientation, can be either :horizontal or :vertical. The default value is :horizontal.
  • :point_color (String.t/0) - The color of the points
  • :point_shape - Shape of the point marks. Circle by default.
  • :point_size (pos_integer/0) - The pixel area of the marks. Note that this value sets the area of the symbol; the side lengths will increase with the square root of this value. The default value is 16.
  • :title (String.t/0) - The title of the graph
  • :width (pos_integer/0 or :container) - Width of the plot. Can either be the width in pixels or :container to indicate that the width of the plot should be the same as its surrounding container.

Encodings Custom Options

All Tucan plots are building a VegaLite specification based on some sane default parameters. Through these encodings options you are free to set any vega-lite supported option to any encoding channel of the plot.

Notice that if set they will be merged with any option set by the plot. Since they have a higher precedence they may override the default settings and affect the generated plot.

You can set an arbitrary keyword list. Notice that the contents are not validated.

  • :color (keyword/0) - Extra vega lite options for the :color encoding. The default value is [].
  • :x (keyword/0) - Extra vega lite options for the :x encoding. The default value is [].
  • :x_offset (keyword/0) - Extra vega lite options for the :x_offset encoding. The default value is [].
  • :y (keyword/0) - Extra vega lite options for the :y encoding. The default value is [].
  • :y_offset (keyword/0) - Extra vega lite options for the :y_offset encoding. The default value is [].

Interactivity Options

  • :tooltip (boolean() | :data | :encoding) - The tooltip text string to show upon mouse hover or an object defining which fields should the tooltip be derived from. Can be one of the following:

    • :encoding - all fields from encoding are used
    • :data - all fields of the highlighted data point are used
    • true - same as :encoding
    • false, nil - no tooltip is used
  • :zoomable (boolean/0) - Whether the plot will be zoomable or not. If set to true you will be able to pan and zoom the plot with your mouse. You can reset to the original view with a double click. The default value is false.

Examples

Assigning a single numeric variable shows the univariate distribution. The default style is the :tick:

Tucan.stripplot(:tips, "total_bill")
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://raw.githubusercontent.com/mwaskom/seaborn-data/master/tips.csv"},"encoding":{"x":{"field":"total_bill","type":"quantitative"}},"mark":"tick"}

For very dense distribution it makes more sense to use the :jitter style in order to reduce overlapping points:

Tucan.stripplot(:tips, "total_bill", style: :jitter, height: 30, width: 300)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://raw.githubusercontent.com/mwaskom/seaborn-data/master/tips.csv"},"encoding":{"x":{"field":"total_bill","type":"quantitative"},"yOffset":{"axis":null,"field":"jitter","type":"quantitative"}},"height":30,"mark":{"size":16,"type":"point"},"transform":[{"as":"jitter","calculate":"sqrt(-2*log(random()))*cos(2*PI*random())"}],"width":300}

You can set the :group_by option in order to add a second dimension. Notice that the field must be categorical.

Tucan.stripplot(:tips, "total_bill", group_by: "day", style: :jitter)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://raw.githubusercontent.com/mwaskom/seaborn-data/master/tips.csv"},"encoding":{"x":{"field":"total_bill","type":"quantitative"},"y":{"field":"day","type":"nominal"},"yOffset":{"axis":null,"field":"jitter","type":"quantitative"}},"mark":{"size":16,"type":"point"},"transform":[{"as":"jitter","calculate":"sqrt(-2*log(random()))*cos(2*PI*random())"}]}

The plot would be more clear if you also colored the points with the same field:

Tucan.stripplot(:tips, "total_bill", group_by: "day", style: :jitter)
|> Tucan.color_by("day")
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://raw.githubusercontent.com/mwaskom/seaborn-data/master/tips.csv"},"encoding":{"color":{"field":"day"},"x":{"field":"total_bill","type":"quantitative"},"y":{"field":"day","type":"nominal"},"yOffset":{"axis":null,"field":"jitter","type":"quantitative"}},"mark":{"size":16,"type":"point"},"transform":[{"as":"jitter","calculate":"sqrt(-2*log(random()))*cos(2*PI*random())"}]}

You can use :uniform distribution instead of the default (:normal). Below you can see both side by side:

normal =
  Tucan.stripplot(:movies, "IMDB Rating",
    group_by: "Major Genre",
    style: :jitter,
    point_size: 2,
    width: 300
  )
  |> Tucan.color_by("Major Genre", type: :nominal)
  |> Tucan.set_title("Gaussian jittering")
  |> Tucan.Legend.set_enabled(:color, false)

uniform =
  Tucan.stripplot(:movies, "IMDB Rating",
    group_by: "Major Genre",
    style: :jitter,
    jitter_mode: :uniform,
    point_size: 2,
    width: 300
  )
  |> Tucan.color_by("Major Genre", type: :nominal)
  |> Tucan.set_title("Uniform jittering")
  |> Tucan.Legend.set_enabled(:color, false)
  |> Tucan.Axes.set_enabled(:y, false)

Tucan.hconcat([normal, uniform])
|> VegaLite.resolve(:scale, y_offset: :independent, y: :shared)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","hconcat":[{"data":{"url":"https://vega.github.io/editor/data/movies.json"},"encoding":{"color":{"field":"Major Genre","legend":null,"type":"nominal"},"x":{"field":"IMDB Rating","type":"quantitative"},"y":{"field":"Major Genre","type":"nominal"},"yOffset":{"axis":null,"field":"jitter","type":"quantitative"}},"mark":{"size":2,"type":"point"},"title":{"text":"Gaussian jittering"},"transform":[{"as":"jitter","calculate":"sqrt(-2*log(random()))*cos(2*PI*random())"}],"width":300},{"data":{"url":"https://vega.github.io/editor/data/movies.json"},"encoding":{"color":{"field":"Major Genre","legend":null,"type":"nominal"},"x":{"field":"IMDB Rating","type":"quantitative"},"y":{"axis":null,"field":"Major Genre","type":"nominal"},"yOffset":{"axis":null,"field":"jitter","type":"quantitative"}},"mark":{"size":2,"type":"point"},"title":{"text":"Uniform jittering"},"transform":[{"as":"jitter","calculate":"random()"}],"width":300}],"resolve":{"scale":{"y":"shared","yOffset":"independent"}}}

You can also color by a distinct variable to show a multi-dimensional relationship:

Tucan.stripplot(:tips, "total_bill", group_by: "day", style: :jitter)
|> Tucan.color_by("sex")
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://raw.githubusercontent.com/mwaskom/seaborn-data/master/tips.csv"},"encoding":{"color":{"field":"sex"},"x":{"field":"total_bill","type":"quantitative"},"y":{"field":"day","type":"nominal"},"yOffset":{"axis":null,"field":"jitter","type":"quantitative"}},"mark":{"size":16,"type":"point"},"transform":[{"as":"jitter","calculate":"sqrt(-2*log(random()))*cos(2*PI*random())"}]}

or you can color by a numerical variable:

Tucan.stripplot(:tips, "total_bill", group_by: "day", style: :jitter)
|> Tucan.color_by("size", type: :ordinal)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://raw.githubusercontent.com/mwaskom/seaborn-data/master/tips.csv"},"encoding":{"color":{"field":"size","type":"ordinal"},"x":{"field":"total_bill","type":"quantitative"},"y":{"field":"day","type":"nominal"},"yOffset":{"axis":null,"field":"jitter","type":"quantitative"}},"mark":{"size":16,"type":"point"},"transform":[{"as":"jitter","calculate":"sqrt(-2*log(random()))*cos(2*PI*random())"}]}

You could draw the same with points but without jittering:

Tucan.stripplot(:tips, "total_bill", group_by: "day", style: :point)
|> Tucan.color_by("sex")
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://raw.githubusercontent.com/mwaskom/seaborn-data/master/tips.csv"},"encoding":{"color":{"field":"sex"},"x":{"field":"total_bill","type":"quantitative"},"y":{"field":"day","type":"nominal"}},"mark":{"size":16,"type":"point"}}

or with ticks which is the default one:

Tucan.stripplot(:tips, "total_bill", group_by: "day", style: :tick)
|> Tucan.color_by("sex")
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://raw.githubusercontent.com/mwaskom/seaborn-data/master/tips.csv"},"encoding":{"color":{"field":"sex"},"x":{"field":"total_bill","type":"quantitative"},"y":{"field":"day","type":"nominal"}},"mark":"tick"}

You can set the :orient flag to :vertical to change the orientation:

Tucan.stripplot(:tips, "total_bill", group_by: "day", style: :jitter, orient: :vertical)
|> Tucan.color_by("sex")
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://raw.githubusercontent.com/mwaskom/seaborn-data/master/tips.csv"},"encoding":{"color":{"field":"sex"},"x":{"field":"day","type":"nominal"},"xOffset":{"axis":null,"field":"jitter","type":"quantitative"},"y":{"field":"total_bill","type":"quantitative"}},"mark":{"size":16,"type":"point"},"transform":[{"as":"jitter","calculate":"sqrt(-2*log(random()))*cos(2*PI*random())"}]}

Composite Plots

Link to this function

jointplot(plotdata, x, y, opts \\ [])

View Source
@spec jointplot(plotdata :: plotdata(), x :: field(), y :: field(), opts :: keyword()) ::
  VegaLite.t()

Returns the specification of a jointplot.

A jointplot is a plot of two numerical variables along with marginal univariate graphs. If no options are set the joint is a scatter plot and the marginal are the histograms of the two variables.

Marginal plots dimensions

By default a jointplot will have a square shape, e.g. it will have the same width and height. The :width option affects the width of the central (joint) plot.

For the marginal distributions you can the :ratio option which specifies the ratio of joint axes height to marginal axes height.

Options

  • :joint - The plot type to be used for the main (joint) plot. Can be one of :scatter and :density_heatmap. The default value is :scatter.
  • :joint_opts (keyword/0) - Arbitrary options list for the joint plot. The supported options depend on the selected :joint type. The default value is [].
  • :marginal - The plot type to be used for the marginal plots. Can be one of :histogram and :density. The default value is :histogram.
  • :marginal_opts (keyword/0) - Arbitrary options list for the marginal plots. The supported options depend on the selected :marginal type. Notice that if :x, :y encodings options are set, they are considered to be defined for the default orientation, and will be flipped to :y, :x respectively for the vertical marginal plot. The default value is [].
  • :ratio (float/0) - The ratio of the marginal plots secondary dimension with respect to the joint plot dimension. The default value is 0.45.

Data Grouping Options

  • :color_by (String.t/0) - If set a data field that will be used for coloring the data. It is considered :nominal by default.

Styling Options

  • :fill_opacity (number/0) - The fill opacity of the plotted elements. The default value is 1.
  • :spacing (pos_integer/0) - The spacing between the marginals and the joint plot. The default value is 15.
  • :title (String.t/0) - The title of the graph
  • :width (pos_integer/0 or :container) - The dimension of the central (joint) plot. The same value is used for both the width and height of the plot. The default value is 200.

Examples

A simple joint plot between two variables.

Tucan.jointplot(:iris, "petal_width", "petal_length", width: 200)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","bounds":"flush","data":{"url":"https://gist.githubusercontent.com/curran/a08a1080b88344b0c8a7/raw/0e7a9b0a5d22642a06d3d5b9bcbad9890c8ee534/iris.csv"},"spacing":15,"vconcat":[{"encoding":{"x":{"axis":null,"bin":{"binned":true},"field":"bin_petal_width","title":"petal_width"},"x2":{"field":"bin_petal_width_end"},"y":{"field":"count_petal_width","stack":null,"type":"quantitative"}},"height":90,"mark":{"fillOpacity":1,"type":"bar"},"transform":[{"as":"bin_petal_width","bin":true,"field":"petal_width"},{"aggregate":[{"as":"count_petal_width","op":"count"}],"groupby":["bin_petal_width","bin_petal_width_end"]}]},{"bounds":"flush","hconcat":[{"encoding":{"x":{"field":"petal_width","scale":{"zero":false},"type":"quantitative"},"y":{"field":"petal_length","scale":{"zero":false},"type":"quantitative"}},"height":200,"mark":{"fillOpacity":1,"type":"point"},"width":200},{"encoding":{"x":{"field":"count_petal_length","stack":null,"type":"quantitative"},"y":{"axis":null,"bin":{"binned":true},"field":"bin_petal_length","title":"petal_length"},"y2":{"field":"bin_petal_length_end"}},"mark":{"fillOpacity":1,"type":"bar"},"transform":[{"as":"bin_petal_length","bin":true,"field":"petal_length"},{"aggregate":[{"as":"count_petal_length","op":"count"}],"groupby":["bin_petal_length","bin_petal_length_end"]}],"width":90}],"spacing":15}]}

You can also pass :color_by to apply a semantic grouping. If set it will be applied both to the joint and the marginal plots.

Tucan.jointplot(
  :iris,
  "petal_width",
  "petal_length",
  color_by: "species",
  fill_opacity: 0.5,
  width: 200
)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","bounds":"flush","data":{"url":"https://gist.githubusercontent.com/curran/a08a1080b88344b0c8a7/raw/0e7a9b0a5d22642a06d3d5b9bcbad9890c8ee534/iris.csv"},"spacing":15,"vconcat":[{"encoding":{"color":{"field":"species"},"x":{"axis":null,"bin":{"binned":true},"field":"bin_petal_width","title":"petal_width"},"x2":{"field":"bin_petal_width_end"},"y":{"field":"count_petal_width","stack":null,"type":"quantitative"}},"height":90,"mark":{"fillOpacity":0.5,"type":"bar"},"transform":[{"as":"bin_petal_width","bin":true,"field":"petal_width"},{"aggregate":[{"as":"count_petal_width","op":"count"}],"groupby":["bin_petal_width","bin_petal_width_end","species"]}]},{"bounds":"flush","hconcat":[{"encoding":{"color":{"field":"species","type":"nominal"},"x":{"field":"petal_width","scale":{"zero":false},"type":"quantitative"},"y":{"field":"petal_length","scale":{"zero":false},"type":"quantitative"}},"height":200,"mark":{"fillOpacity":0.5,"type":"point"},"width":200},{"encoding":{"color":{"field":"species"},"x":{"field":"count_petal_length","stack":null,"type":"quantitative"},"y":{"axis":null,"bin":{"binned":true},"field":"bin_petal_length","title":"petal_length"},"y2":{"field":"bin_petal_length_end"}},"mark":{"fillOpacity":0.5,"type":"bar"},"transform":[{"as":"bin_petal_length","bin":true,"field":"petal_length"},{"aggregate":[{"as":"count_petal_length","op":"count"}],"groupby":["bin_petal_length","bin_petal_length_end","species"]}],"width":90}],"spacing":15}]}

You can change the type of the join plot and the marginal distributions:

Tucan.jointplot(
  :penguins,
  "Beak Length (mm)",
  "Beak Depth (mm)",
  joint: :density_heatmap,
  marginal: :density,
  ratio: 0.3
)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","bounds":"flush","data":{"url":"https://raw.githubusercontent.com/vega/vega-datasets/next/data/penguins.json"},"spacing":15,"vconcat":[{"encoding":{"x":{"axis":null,"field":"value","scale":{"zero":false},"type":"quantitative"},"y":{"field":"density","stack":null,"type":"quantitative"}},"height":60,"mark":{"fillOpacity":1,"orient":"vertical","type":"area"},"transform":[{"counts":false,"cumulative":false,"density":"Beak Length (mm)","maxsteps":200,"minsteps":25}]},{"bounds":"flush","hconcat":[{"encoding":{"color":{"aggregate":"count","type":"quantitative"},"x":{"bin":true,"field":"Beak Length (mm)","type":"quantitative"},"y":{"bin":true,"field":"Beak Depth (mm)","type":"quantitative"}},"height":200,"mark":{"fillOpacity":1,"type":"rect"},"width":200},{"encoding":{"x":{"field":"density","stack":null,"type":"quantitative"},"y":{"axis":null,"field":"value","scale":{"zero":false},"type":"quantitative"}},"mark":{"fillOpacity":1,"orient":"horizontal","type":"area"},"transform":[{"counts":false,"cumulative":false,"density":"Beak Depth (mm)","maxsteps":200,"minsteps":25}],"width":60}],"spacing":15}]}
Link to this function

pairplot(plotdata, fields, opts \\ [])

View Source
@spec pairplot(plotdata :: plotdata(), fields :: [String.t()], opts :: keyword()) ::
  VegaLite.t()

Plot pairwise relationships in a dataset.

This function expects an array of fields to be provided. A grid will be created where each numeric variable in fields will be shared across the y-axes across a single row and the x-axes across a single column.

Numerical field types

Notice that currently pairplot/3 works only with numerical (:quantitative) variables. If you need to create a pair plot containing other variable types you need to manually build the grid using the VegaLite concatenation operations.

Options

  • :diagonal - The plot type to be used for the diagonal subplots. Can be one on :scatter, :density and :histogram. The default value is :scatter.

  • :plot_fn (function of arity 3) - An optional function for customizing the look any subplot. It expects a function with the following signature:

    (vl :: VegaLite.t(), row :: {String.t(), integer()}, column :: {String.t(), integer()})
      :: VegaLite.t()

    where both row and column are tuples containing the index and field of the current and row and column respectively.

    You are free to specify any function for every cell of the grid.

Data Options

  • :only - A subset of fields to pick from the data. Applicable only if tabular data are provided.

Styling Options

  • :height (pos_integer/0 or :container) - Height of the plot. Can either be the height in pixels or :container to indicate that the height of the plot should be the same as its surrounding container.
  • :title (String.t/0) - The title of the graph
  • :width (pos_integer/0 or :container) - Width of the plot. Can either be the width in pixels or :container to indicate that the width of the plot should be the same as its surrounding container.

Notice that if set width and height will be applied to individual sub plots. On the other hand title is applied to the composite plot.

Examples

By default a scatter plot will be drawn for all pairwise plots:

fields = ["petal_width", "petal_length", "sepal_width", "sepal_length"]

Tucan.pairplot(:iris, fields, width: 130, height: 130)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","columns":4,"concat":[{"encoding":{"x":{"axis":{"title":null},"field":"petal_width","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":"petal_width"},"field":"petal_width","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"x":{"axis":{"title":null},"field":"petal_length","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"petal_width","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"x":{"axis":{"title":null},"field":"sepal_width","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"petal_width","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"x":{"axis":{"title":null},"field":"sepal_length","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"petal_width","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"x":{"axis":{"title":null},"field":"petal_width","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":"petal_length"},"field":"petal_length","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"x":{"axis":{"title":null},"field":"petal_length","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"petal_length","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"x":{"axis":{"title":null},"field":"sepal_width","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"petal_length","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"x":{"axis":{"title":null},"field":"sepal_length","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"petal_length","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"x":{"axis":{"title":null},"field":"petal_width","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":"sepal_width"},"field":"sepal_width","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"x":{"axis":{"title":null},"field":"petal_length","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"sepal_width","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"x":{"axis":{"title":null},"field":"sepal_width","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"sepal_width","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"x":{"axis":{"title":null},"field":"sepal_length","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"sepal_width","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"x":{"axis":{"title":"petal_width"},"field":"petal_width","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":"sepal_length"},"field":"sepal_length","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"x":{"axis":{"title":"petal_length"},"field":"petal_length","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"sepal_length","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"x":{"axis":{"title":"sepal_width"},"field":"sepal_width","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"sepal_length","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"x":{"axis":{"title":"sepal_length"},"field":"sepal_length","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"sepal_length","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130}],"data":{"url":"https://gist.githubusercontent.com/curran/a08a1080b88344b0c8a7/raw/0e7a9b0a5d22642a06d3d5b9bcbad9890c8ee534/iris.csv"}}

You can color the points by another field in to add some semantic mapping. Notice that you need the recursive option to true for the grouping to be applied on all internal subplots.

fields = ["petal_width", "petal_length", "sepal_width", "sepal_length"]

Tucan.pairplot(:iris, fields, width: 130, height: 130)
|> Tucan.color_by("species", recursive: true)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","columns":4,"concat":[{"encoding":{"color":{"field":"species"},"x":{"axis":{"title":null},"field":"petal_width","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":"petal_width"},"field":"petal_width","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"color":{"field":"species"},"x":{"axis":{"title":null},"field":"petal_length","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"petal_width","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"color":{"field":"species"},"x":{"axis":{"title":null},"field":"sepal_width","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"petal_width","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"color":{"field":"species"},"x":{"axis":{"title":null},"field":"sepal_length","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"petal_width","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"color":{"field":"species"},"x":{"axis":{"title":null},"field":"petal_width","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":"petal_length"},"field":"petal_length","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"color":{"field":"species"},"x":{"axis":{"title":null},"field":"petal_length","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"petal_length","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"color":{"field":"species"},"x":{"axis":{"title":null},"field":"sepal_width","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"petal_length","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"color":{"field":"species"},"x":{"axis":{"title":null},"field":"sepal_length","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"petal_length","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"color":{"field":"species"},"x":{"axis":{"title":null},"field":"petal_width","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":"sepal_width"},"field":"sepal_width","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"color":{"field":"species"},"x":{"axis":{"title":null},"field":"petal_length","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"sepal_width","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"color":{"field":"species"},"x":{"axis":{"title":null},"field":"sepal_width","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"sepal_width","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"color":{"field":"species"},"x":{"axis":{"title":null},"field":"sepal_length","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"sepal_width","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"color":{"field":"species"},"x":{"axis":{"title":"petal_width"},"field":"petal_width","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":"sepal_length"},"field":"sepal_length","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"color":{"field":"species"},"x":{"axis":{"title":"petal_length"},"field":"petal_length","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"sepal_length","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"color":{"field":"species"},"x":{"axis":{"title":"sepal_width"},"field":"sepal_width","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"sepal_length","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"color":{"field":"species"},"x":{"axis":{"title":"sepal_length"},"field":"sepal_length","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"sepal_length","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130}],"data":{"url":"https://gist.githubusercontent.com/curran/a08a1080b88344b0c8a7/raw/0e7a9b0a5d22642a06d3d5b9bcbad9890c8ee534/iris.csv"}}

By specifying the :diagonal option you can change the default plot for the diagonal elements to a histogram:

fields = ["petal_width", "petal_length", "sepal_width", "sepal_length"]

Tucan.pairplot(:iris, fields, width: 130, height: 130, diagonal: :histogram)
|> Tucan.color_by("species", recursive: true)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","columns":4,"concat":[{"encoding":{"color":{"field":"species"},"x":{"axis":{"title":null},"bin":{"binned":true},"field":"bin_petal_width","title":"petal_width"},"x2":{"field":"bin_petal_width_end"},"y":{"axis":{"title":"petal_width"},"field":"count_petal_width","stack":null,"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"bar"},"transform":[{"as":"bin_petal_width","bin":true,"field":"petal_width"},{"aggregate":[{"as":"count_petal_width","op":"count"}],"groupby":["bin_petal_width","bin_petal_width_end"]}],"width":130},{"encoding":{"color":{"field":"species"},"x":{"axis":{"title":null},"field":"petal_length","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"petal_width","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"color":{"field":"species"},"x":{"axis":{"title":null},"field":"sepal_width","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"petal_width","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"color":{"field":"species"},"x":{"axis":{"title":null},"field":"sepal_length","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"petal_width","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"color":{"field":"species"},"x":{"axis":{"title":null},"field":"petal_width","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":"petal_length"},"field":"petal_length","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"color":{"field":"species"},"x":{"axis":{"title":null},"bin":{"binned":true},"field":"bin_petal_length","title":"petal_length"},"x2":{"field":"bin_petal_length_end"},"y":{"axis":{"title":null},"field":"count_petal_length","stack":null,"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"bar"},"transform":[{"as":"bin_petal_length","bin":true,"field":"petal_length"},{"aggregate":[{"as":"count_petal_length","op":"count"}],"groupby":["bin_petal_length","bin_petal_length_end"]}],"width":130},{"encoding":{"color":{"field":"species"},"x":{"axis":{"title":null},"field":"sepal_width","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"petal_length","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"color":{"field":"species"},"x":{"axis":{"title":null},"field":"sepal_length","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"petal_length","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"color":{"field":"species"},"x":{"axis":{"title":null},"field":"petal_width","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":"sepal_width"},"field":"sepal_width","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"color":{"field":"species"},"x":{"axis":{"title":null},"field":"petal_length","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"sepal_width","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"color":{"field":"species"},"x":{"axis":{"title":null},"bin":{"binned":true},"field":"bin_sepal_width","title":"sepal_width"},"x2":{"field":"bin_sepal_width_end"},"y":{"axis":{"title":null},"field":"count_sepal_width","stack":null,"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"bar"},"transform":[{"as":"bin_sepal_width","bin":true,"field":"sepal_width"},{"aggregate":[{"as":"count_sepal_width","op":"count"}],"groupby":["bin_sepal_width","bin_sepal_width_end"]}],"width":130},{"encoding":{"color":{"field":"species"},"x":{"axis":{"title":null},"field":"sepal_length","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"sepal_width","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"color":{"field":"species"},"x":{"axis":{"title":"petal_width"},"field":"petal_width","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":"sepal_length"},"field":"sepal_length","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"color":{"field":"species"},"x":{"axis":{"title":"petal_length"},"field":"petal_length","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"sepal_length","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"color":{"field":"species"},"x":{"axis":{"title":"sepal_width"},"field":"sepal_width","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"sepal_length","scale":{"zero":false},"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"point"},"width":130},{"encoding":{"color":{"field":"species"},"x":{"axis":{"title":"sepal_length"},"bin":{"binned":true},"field":"bin_sepal_length","title":"sepal_length"},"x2":{"field":"bin_sepal_length_end"},"y":{"axis":{"title":null},"field":"count_sepal_length","stack":null,"type":"quantitative"}},"height":130,"mark":{"fillOpacity":1,"type":"bar"},"transform":[{"as":"bin_sepal_length","bin":true,"field":"sepal_length"},{"aggregate":[{"as":"count_sepal_length","op":"count"}],"groupby":["bin_sepal_length","bin_sepal_length_end"]}],"width":130}],"data":{"url":"https://gist.githubusercontent.com/curran/a08a1080b88344b0c8a7/raw/0e7a9b0a5d22642a06d3d5b9bcbad9890c8ee534/iris.csv"}}

Additionally you have the option to configure a plot_fn with which we can go crazy and modify any part of the grid based on our needs. plot_fn should accept as input a VegaLite struct and two tuples containing the row and column fields and indexes. In the following example we draw differently the diagonal, the lower and the upper grid. Notice that we don't call color_by/3 since we color differently the plots based on their index positions.

Tucan.pairplot(:iris, ["petal_width", "petal_length", "sepal_width", "sepal_length"],
  width: 150,
  height: 150,
  plot_fn: fn vl, {row_field, row_index}, {col_field, col_index} ->
    cond do
      # For the first two diagonal elements we plot a histogram, no
      row_index == col_index and row_index < 2 ->
        Tucan.histogram(vl, row_field)

      row_index == 2 and col_index == 2 ->
        Tucan.stripplot(vl, row_field, group_by: "species", style: :tick)
        |> Tucan.color_by("species")
        |> Tucan.Axes.put_options(:y, labels: false)

      # For the other diagonal plots we plot a histogram colored_by the species
      row_index == col_index ->
        Tucan.histogram(vl, row_field, color_by: "species")

      # For the upper part of the diagram we apply a scatter plot
      row_index < col_index ->
        Tucan.scatter(vl, col_field, row_field)
        |> Tucan.color_by("species")

      # for anything else scatter plot with a quantitative color scale
      # and size
      true ->
        Tucan.scatter(vl, col_field, row_field)
        |> Tucan.size_by("petal_width", type: :quantitative)
    end
  end
)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","columns":4,"concat":[{"encoding":{"x":{"axis":{"title":null},"bin":{"binned":true},"field":"bin_petal_width","title":"petal_width"},"x2":{"field":"bin_petal_width_end"},"y":{"axis":{"title":"petal_width"},"field":"count_petal_width","stack":null,"type":"quantitative"}},"height":150,"mark":{"fillOpacity":1,"type":"bar"},"transform":[{"as":"bin_petal_width","bin":true,"field":"petal_width"},{"aggregate":[{"as":"count_petal_width","op":"count"}],"groupby":["bin_petal_width","bin_petal_width_end"]}],"width":150},{"encoding":{"color":{"field":"species"},"x":{"axis":{"title":null},"field":"petal_length","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"petal_width","scale":{"zero":false},"type":"quantitative"}},"height":150,"mark":{"fillOpacity":1,"type":"point"},"width":150},{"encoding":{"color":{"field":"species"},"x":{"axis":{"title":null},"field":"sepal_width","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"petal_width","scale":{"zero":false},"type":"quantitative"}},"height":150,"mark":{"fillOpacity":1,"type":"point"},"width":150},{"encoding":{"color":{"field":"species"},"x":{"axis":{"title":null},"field":"sepal_length","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"petal_width","scale":{"zero":false},"type":"quantitative"}},"height":150,"mark":{"fillOpacity":1,"type":"point"},"width":150},{"encoding":{"size":{"field":"petal_width","type":"quantitative"},"x":{"axis":{"title":null},"field":"petal_width","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":"petal_length"},"field":"petal_length","scale":{"zero":false},"type":"quantitative"}},"height":150,"mark":{"fillOpacity":1,"type":"point"},"width":150},{"encoding":{"x":{"axis":{"title":null},"bin":{"binned":true},"field":"bin_petal_length","title":"petal_length"},"x2":{"field":"bin_petal_length_end"},"y":{"axis":{"title":null},"field":"count_petal_length","stack":null,"type":"quantitative"}},"height":150,"mark":{"fillOpacity":1,"type":"bar"},"transform":[{"as":"bin_petal_length","bin":true,"field":"petal_length"},{"aggregate":[{"as":"count_petal_length","op":"count"}],"groupby":["bin_petal_length","bin_petal_length_end"]}],"width":150},{"encoding":{"color":{"field":"species"},"x":{"axis":{"title":null},"field":"sepal_width","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"petal_length","scale":{"zero":false},"type":"quantitative"}},"height":150,"mark":{"fillOpacity":1,"type":"point"},"width":150},{"encoding":{"color":{"field":"species"},"x":{"axis":{"title":null},"field":"sepal_length","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"petal_length","scale":{"zero":false},"type":"quantitative"}},"height":150,"mark":{"fillOpacity":1,"type":"point"},"width":150},{"encoding":{"size":{"field":"petal_width","type":"quantitative"},"x":{"axis":{"title":null},"field":"petal_width","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":"sepal_width"},"field":"sepal_width","scale":{"zero":false},"type":"quantitative"}},"height":150,"mark":{"fillOpacity":1,"type":"point"},"width":150},{"encoding":{"size":{"field":"petal_width","type":"quantitative"},"x":{"axis":{"title":null},"field":"petal_length","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"sepal_width","scale":{"zero":false},"type":"quantitative"}},"height":150,"mark":{"fillOpacity":1,"type":"point"},"width":150},{"encoding":{"color":{"field":"species"},"x":{"axis":{"title":null},"field":"sepal_width","type":"quantitative"},"y":{"axis":{"labels":false,"title":null},"field":"species","type":"nominal"}},"height":150,"mark":"tick","width":150},{"encoding":{"color":{"field":"species"},"x":{"axis":{"title":null},"field":"sepal_length","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"sepal_width","scale":{"zero":false},"type":"quantitative"}},"height":150,"mark":{"fillOpacity":1,"type":"point"},"width":150},{"encoding":{"size":{"field":"petal_width","type":"quantitative"},"x":{"axis":{"title":"petal_width"},"field":"petal_width","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":"sepal_length"},"field":"sepal_length","scale":{"zero":false},"type":"quantitative"}},"height":150,"mark":{"fillOpacity":1,"type":"point"},"width":150},{"encoding":{"size":{"field":"petal_width","type":"quantitative"},"x":{"axis":{"title":"petal_length"},"field":"petal_length","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"sepal_length","scale":{"zero":false},"type":"quantitative"}},"height":150,"mark":{"fillOpacity":1,"type":"point"},"width":150},{"encoding":{"size":{"field":"petal_width","type":"quantitative"},"x":{"axis":{"title":"sepal_width"},"field":"sepal_width","scale":{"zero":false},"type":"quantitative"},"y":{"axis":{"title":null},"field":"sepal_length","scale":{"zero":false},"type":"quantitative"}},"height":150,"mark":{"fillOpacity":1,"type":"point"},"width":150},{"encoding":{"color":{"field":"species"},"x":{"axis":{"title":"sepal_length"},"bin":{"binned":true},"field":"bin_sepal_length","title":"sepal_length"},"x2":{"field":"bin_sepal_length_end"},"y":{"axis":{"title":null},"field":"count_sepal_length","stack":null,"type":"quantitative"}},"height":150,"mark":{"fillOpacity":1,"type":"bar"},"transform":[{"as":"bin_sepal_length","bin":true,"field":"sepal_length"},{"aggregate":[{"as":"count_sepal_length","op":"count"}],"groupby":["bin_sepal_length","bin_sepal_length_end","species"]}],"width":150}],"data":{"url":"https://gist.githubusercontent.com/curran/a08a1080b88344b0c8a7/raw/0e7a9b0a5d22642a06d3d5b9bcbad9890c8ee534/iris.csv"}}

Images

Link to this function

imshow(data, opts \\ [])

View Source
@spec imshow(data :: Nx.Tensor.t(), opts :: keyword()) :: VegaLite.t()

Display data as an image.

The input is expected to be an Nx.Tensor containing 2D scalar data, which will be rendered as a pseudo-color image. The origin is set at the upper left hand corner and rows (first dimension of the array) are displayed horizontally. By setting :origin to :lower you can set the origin to the lower left hand corner.

Options

  • :color_scheme (atom/0) - The color scheme to be used for the image. Should be one of the supported color schemes of Tucan.Scale.set_color_scheme/3. The default value is :viridis.

  • :origin - Place the [0, 0] index of the array in the upper left or lower left corner of the Axes. The convention (the default) :upper is typically used for matrices and images.

    Note that the vertical axis points upward for :lower but downward for :upper.

    data = Nx.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]], type: {:f, 32})
    
    Tucan.hconcat([
      Tucan.imshow(data, width: 200, height: 200, origin: :upper, show_scale: true, tooltip: true)
      |> Tucan.set_title(":upper origin (default)"),
      Tucan.imshow(data, width: 200, height: 200, origin: :lower, show_scale: true, tooltip: true)
      |> Tucan.set_title(":lower origin")
    ])
    {"$schema":"https://vega.github.io/schema/vega-lite/v5.json","hconcat":[{"data":{"values":[{"v":1.0,"x":0,"y":0},{"v":2.0,"x":1,"y":0},{"v":3.0,"x":2,"y":0},{"v":4.0,"x":0,"y":1},{"v":5.0,"x":1,"y":1},{"v":6.0,"x":2,"y":1},{"v":7.0,"x":0,"y":2},{"v":8.0,"x":1,"y":2},{"v":9.0,"x":2,"y":2}]},"encoding":{"color":{"field":"v","legend":{"title":null},"scale":{"reverse":false,"scheme":"viridis"},"type":"quantitative"},"x":{"axis":null,"field":"x","type":"ordinal"},"y":{"axis":null,"field":"y","type":"ordinal"}},"height":200,"mark":{"tooltip":true,"type":"rect"},"title":{"text":":upper origin (default)"},"width":200},{"data":{"values":[{"v":1.0,"x":0,"y":2},{"v":2.0,"x":1,"y":2},{"v":3.0,"x":2,"y":2},{"v":4.0,"x":0,"y":1},{"v":5.0,"x":1,"y":1},{"v":6.0,"x":2,"y":1},{"v":7.0,"x":0,"y":0},{"v":8.0,"x":1,"y":0},{"v":9.0,"x":2,"y":0}]},"encoding":{"color":{"field":"v","legend":{"title":null},"scale":{"reverse":false,"scheme":"viridis"},"type":"quantitative"},"x":{"axis":null,"field":"x","type":"ordinal"},"y":{"axis":null,"field":"y","type":"ordinal"}},"height":200,"mark":{"tooltip":true,"type":"rect"},"title":{"text":":lower origin"},"width":200}]}

    The default value is :upper.

  • :reverse (boolean/0) - Whether the color scheme will be reversed or not. The default value is false.

Styling Options

  • :height (pos_integer/0 or :container) - Height of the plot. Can either be the height in pixels or :container to indicate that the height of the plot should be the same as its surrounding container.
  • :show_scale (boolean/0) - If set the color scale is displayed. The default value is false.
  • :title (String.t/0) - The title of the graph
  • :width (pos_integer/0 or :container) - Width of the plot. Can either be the width in pixels or :container to indicate that the width of the plot should be the same as its surrounding container.

Interactivity Options

  • :tooltip (boolean() | :data | :encoding) - The tooltip text string to show upon mouse hover or an object defining which fields should the tooltip be derived from. Can be one of the following:

    • :encoding - all fields from encoding are used
    • :data - all fields of the highlighted data point are used
    • true - same as :encoding
    • false, nil - no tooltip is used

Examples

In the following examples we use a subset of the MNIST dataset. The data are stored as a serialized Nx.Tensor with shape {images, height, width, 1}.

mnist_path = Path.expand("../../assets/mnist_sample.bin", __DIR__)
images = File.read!(mnist_path) |> Nx.deserialize()

Tucan.imshow(images[[images: 5]], width: 200, height: 200)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"values":[{"v":0,"x":0,"y":0},{"v":0,"x":1,"y":0},{"v":0,"x":2,"y":0},{"v":0,"x":3,"y":0},{"v":0,"x":4,"y":0},{"v":0,"x":5,"y":0},{"v":0,"x":6,"y":0},{"v":0,"x":7,"y":0},{"v":0,"x":8,"y":0},{"v":0,"x":9,"y":0},{"v":0,"x":10,"y":0},{"v":0,"x":11,"y":0},{"v":0,"x":12,"y":0},{"v":0,"x":13,"y":0},{"v":0,"x":14,"y":0},{"v":0,"x":15,"y":0},{"v":0,"x":16,"y":0},{"v":0,"x":17,"y":0},{"v":0,"x":18,"y":0},{"v":0,"x":19,"y":0},{"v":0,"x":20,"y":0},{"v":0,"x":21,"y":0},{"v":0,"x":22,"y":0},{"v":0,"x":23,"y":0},{"v":0,"x":24,"y":0},{"v":0,"x":25,"y":0},{"v":0,"x":26,"y":0},{"v":0,"x":27,"y":0},{"v":0,"x":0,"y":1},{"v":0,"x":1,"y":1},{"v":0,"x":2,"y":1},{"v":0,"x":3,"y":1},{"v":0,"x":4,"y":1},{"v":0,"x":5,"y":1},{"v":0,"x":6,"y":1},{"v":0,"x":7,"y":1},{"v":0,"x":8,"y":1},{"v":0,"x":9,"y":1},{"v":0,"x":10,"y":1},{"v":0,"x":11,"y":1},{"v":0,"x":12,"y":1},{"v":0,"x":13,"y":1},{"v":0,"x":14,"y":1},{"v":0,"x":15,"y":1},{"v":0,"x":16,"y":1},{"v":0,"x":17,"y":1},{"v":0,"x":18,"y":1},{"v":0,"x":19,"y":1},{"v":0,"x":20,"y":1},{"v":0,"x":21,"y":1},{"v":0,"x":22,"y":1},{"v":0,"x":23,"y":1},{"v":0,"x":24,"y":1},{"v":0,"x":25,"y":1},{"v":0,"x":26,"y":1},{"v":0,"x":27,"y":1},{"v":0,"x":0,"y":2},{"v":0,"x":1,"y":2},{"v":0,"x":2,"y":2},{"v":0,"x":3,"y":2},{"v":0,"x":4,"y":2},{"v":0,"x":5,"y":2},{"v":0,"x":6,"y":2},{"v":0,"x":7,"y":2},{"v":0,"x":8,"y":2},{"v":0,"x":9,"y":2},{"v":0,"x":10,"y":2},{"v":0,"x":11,"y":2},{"v":0,"x":12,"y":2},{"v":0,"x":13,"y":2},{"v":0,"x":14,"y":2},{"v":0,"x":15,"y":2},{"v":0,"x":16,"y":2},{"v":0,"x":17,"y":2},{"v":0,"x":18,"y":2},{"v":0,"x":19,"y":2},{"v":0,"x":20,"y":2},{"v":0,"x":21,"y":2},{"v":0,"x":22,"y":2},{"v":0,"x":23,"y":2},{"v":0,"x":24,"y":2},{"v":0,"x":25,"y":2},{"v":0,"x":26,"y":2},{"v":0,"x":27,"y":2},{"v":0,"x":0,"y":3},{"v":0,"x":1,"y":3},{"v":0,"x":2,"y":3},{"v":0,"x":3,"y":3},{"v":0,"x":4,"y":3},{"v":0,"x":5,"y":3},{"v":0,"x":6,"y":3},{"v":0,"x":7,"y":3},{"v":0,"x":8,"y":3},{"v":0,"x":9,"y":3},{"v":0,"x":10,"y":3},{"v":0,"x":11,"y":3},{"v":0,"x":12,"y":3},{"v":0,"x":13,"y":3},{"v":0,"x":14,"y":3},{"v":0,"x":15,"y":3},{"v":0,"x":16,"y":3},{"v":0,"x":17,"y":3},{"v":0,"x":18,"y":3},{"v":0,"x":19,"y":3},{"v":0,"x":20,"y":3},{"v":0,"x":21,"y":3},{"v":0,"x":22,"y":3},{"v":0,"x":23,"y":3},{"v":0,"x":24,"y":3},{"v":0,"x":25,"y":3},{"v":0,"x":26,"y":3},{"v":0,"x":27,"y":3},{"v":0,"x":0,"y":4},{"v":0,"x":1,"y":4},{"v":0,"x":2,"y":4},{"v":0,"x":3,"y":4},{"v":0,"x":4,"y":4},{"v":0,"x":5,"y":4},{"v":0,"x":6,"y":4},{"v":0,"x":7,"y":4},{"v":0,"x":8,"y":4},{"v":0,"x":9,"y":4},{"v":0,"x":10,"y":4},{"v":0,"x":11,"y":4},{"v":0,"x":12,"y":4},{"v":0,"x":13,"y":4},{"v":0,"x":14,"y":4},{"v":0,"x":15,"y":4},{"v":0,"x":16,"y":4},{"v":0,"x":17,"y":4},{"v":0,"x":18,"y":4},{"v":0,"x":19,"y":4},{"v":0,"x":20,"y":4},{"v":0,"x":21,"y":4},{"v":0,"x":22,"y":4},{"v":0,"x":23,"y":4},{"v":0,"x":24,"y":4},{"v":0,"x":25,"y":4},{"v":0,"x":26,"y":4},{"v":0,"x":27,"y":4},{"v":0,"x":0,"y":5},{"v":0,"x":1,"y":5},{"v":0,"x":2,"y":5},{"v":0,"x":3,"y":5},{"v":0,"x":4,"y":5},{"v":0,"x":5,"y":5},{"v":0,"x":6,"y":5},{"v":0,"x":7,"y":5},{"v":0,"x":8,"y":5},{"v":0,"x":9,"y":5},{"v":0,"x":10,"y":5},{"v":0,"x":11,"y":5},{"v":0,"x":12,"y":5},{"v":0,"x":13,"y":5},{"v":0,"x":14,"y":5},{"v":13,"x":15,"y":5},{"v":25,"x":16,"y":5},{"v":100,"x":17,"y":5},{"v":122,"x":18,"y":5},{"v":7,"x":19,"y":5},{"v":0,"x":20,"y":5},{"v":0,"x":21,"y":5},{"v":0,"x":22,"y":5},{"v":0,"x":23,"y":5},{"v":0,"x":24,"y":5},{"v":0,"x":25,"y":5},{"v":0,"x":26,"y":5},{"v":0,"x":27,"y":5},{"v":0,"x":0,"y":6},{"v":0,"x":1,"y":6},{"v":0,"x":2,"y":6},{"v":0,"x":3,"y":6},{"v":0,"x":4,"y":6},{"v":0,"x":5,"y":6},{"v":0,"x":6,"y":6},{"v":0,"x":7,"y":6},{"v":0,"x":8,"y":6},{"v":0,"x":9,"y":6},{"v":0,"x":10,"y":6},{"v":0,"x":11,"y":6},{"v":0,"x":12,"y":6},{"v":33,"x":13,"y":6},{"v":151,"x":14,"y":6},{"v":208,"x":15,"y":6},{"v":252,"x":16,"y":6},{"v":252,"x":17,"y":6},{"v":252,"x":18,"y":6},{"v":146,"x":19,"y":6},{"v":0,"x":20,"y":6},{"v":0,"x":21,"y":6},{"v":0,"x":22,"y":6},{"v":0,"x":23,"y":6},{"v":0,"x":24,"y":6},{"v":0,"x":25,"y":6},{"v":0,"x":26,"y":6},{"v":0,"x":27,"y":6},{"v":0,"x":0,"y":7},{"v":0,"x":1,"y":7},{"v":0,"x":2,"y":7},{"v":0,"x":3,"y":7},{"v":0,"x":4,"y":7},{"v":0,"x":5,"y":7},{"v":0,"x":6,"y":7},{"v":0,"x":7,"y":7},{"v":0,"x":8,"y":7},{"v":0,"x":9,"y":7},{"v":0,"x":10,"y":7},{"v":40,"x":11,"y":7},{"v":152,"x":12,"y":7},{"v":244,"x":13,"y":7},{"v":252,"x":14,"y":7},{"v":253,"x":15,"y":7},{"v":224,"x":16,"y":7},{"v":211,"x":17,"y":7},{"v":252,"x":18,"y":7},{"v":232,"x":19,"y":7},{"v":40,"x":20,"y":7},{"v":0,"x":21,"y":7},{"v":0,"x":22,"y":7},{"v":0,"x":23,"y":7},{"v":0,"x":24,"y":7},{"v":0,"x":25,"y":7},{"v":0,"x":26,"y":7},{"v":0,"x":27,"y":7},{"v":0,"x":0,"y":8},{"v":0,"x":1,"y":8},{"v":0,"x":2,"y":8},{"v":0,"x":3,"y":8},{"v":0,"x":4,"y":8},{"v":0,"x":5,"y":8},{"v":0,"x":6,"y":8},{"v":0,"x":7,"y":8},{"v":0,"x":8,"y":8},{"v":15,"x":9,"y":8},{"v":152,"x":10,"y":8},{"v":239,"x":11,"y":8},{"v":252,"x":12,"y":8},{"v":252,"x":13,"y":8},{"v":252,"x":14,"y":8},{"v":216,"x":15,"y":8},{"v":31,"x":16,"y":8},{"v":37,"x":17,"y":8},{"v":252,"x":18,"y":8},{"v":252,"x":19,"y":8},{"v":60,"x":20,"y":8},{"v":0,"x":21,"y":8},{"v":0,"x":22,"y":8},{"v":0,"x":23,"y":8},{"v":0,"x":24,"y":8},{"v":0,"x":25,"y":8},{"v":0,"x":26,"y":8},{"v":0,"x":27,"y":8},{"v":0,"x":0,"y":9},{"v":0,"x":1,"y":9},{"v":0,"x":2,"y":9},{"v":0,"x":3,"y":9},{"v":0,"x":4,"y":9},{"v":0,"x":5,"y":9},{"v":0,"x":6,"y":9},{"v":0,"x":7,"y":9},{"v":0,"x":8,"y":9},{"v":96,"x":9,"y":9},{"v":252,"x":10,"y":9},{"v":252,"x":11,"y":9},{"v":252,"x":12,"y":9},{"v":252,"x":13,"y":9},{"v":217,"x":14,"y":9},{"v":29,"x":15,"y":9},{"v":0,"x":16,"y":9},{"v":37,"x":17,"y":9},{"v":252,"x":18,"y":9},{"v":252,"x":19,"y":9},{"v":60,"x":20,"y":9},{"v":0,"x":21,"y":9},{"v":0,"x":22,"y":9},{"v":0,"x":23,"y":9},{"v":0,"x":24,"y":9},{"v":0,"x":25,"y":9},{"v":0,"x":26,"y":9},{"v":0,"x":27,"y":9},{"v":0,"x":0,"y":10},{"v":0,"x":1,"y":10},{"v":0,"x":2,"y":10},{"v":0,"x":3,"y":10},{"v":0,"x":4,"y":10},{"v":0,"x":5,"y":10},{"v":0,"x":6,"y":10},{"v":0,"x":7,"y":10},{"v":0,"x":8,"y":10},{"v":181,"x":9,"y":10},{"v":252,"x":10,"y":10},{"v":252,"x":11,"y":10},{"v":220,"x":12,"y":10},{"v":167,"x":13,"y":10},{"v":30,"x":14,"y":10},{"v":0,"x":15,"y":10},{"v":0,"x":16,"y":10},{"v":77,"x":17,"y":10},{"v":252,"x":18,"y":10},{"v":252,"x":19,"y":10},{"v":60,"x":20,"y":10},{"v":0,"x":21,"y":10},{"v":0,"x":22,"y":10},{"v":0,"x":23,"y":10},{"v":0,"x":24,"y":10},{"v":0,"x":25,"y":10},{"v":0,"x":26,"y":10},{"v":0,"x":27,"y":10},{"v":0,"x":0,"y":11},{"v":0,"x":1,"y":11},{"v":0,"x":2,"y":11},{"v":0,"x":3,"y":11},{"v":0,"x":4,"y":11},{"v":0,"x":5,"y":11},{"v":0,"x":6,"y":11},{"v":0,"x":7,"y":11},{"v":0,"x":8,"y":11},{"v":26,"x":9,"y":11},{"v":128,"x":10,"y":11},{"v":58,"x":11,"y":11},{"v":22,"x":12,"y":11},{"v":0,"x":13,"y":11},{"v":0,"x":14,"y":11},{"v":0,"x":15,"y":11},{"v":0,"x":16,"y":11},{"v":100,"x":17,"y":11},{"v":252,"x":18,"y":11},{"v":252,"x":19,"y":11},{"v":60,"x":20,"y":11},{"v":0,"x":21,"y":11},{"v":0,"x":22,"y":11},{"v":0,"x":23,"y":11},{"v":0,"x":24,"y":11},{"v":0,"x":25,"y":11},{"v":0,"x":26,"y":11},{"v":0,"x":27,"y":11},{"v":0,"x":0,"y":12},{"v":0,"x":1,"y":12},{"v":0,"x":2,"y":12},{"v":0,"x":3,"y":12},{"v":0,"x":4,"y":12},{"v":0,"x":5,"y":12},{"v":0,"x":6,"y":12},{"v":0,"x":7,"y":12},{"v":0,"x":8,"y":12},{"v":0,"x":9,"y":12},{"v":0,"x":10,"y":12},{"v":0,"x":11,"y":12},{"v":0,"x":12,"y":12},{"v":0,"x":13,"y":12},{"v":0,"x":14,"y":12},{"v":0,"x":15,"y":12},{"v":0,"x":16,"y":12},{"v":157,"x":17,"y":12},{"v":252,"x":18,"y":12},{"v":252,"x":19,"y":12},{"v":60,"x":20,"y":12},{"v":0,"x":21,"y":12},{"v":0,"x":22,"y":12},{"v":0,"x":23,"y":12},{"v":0,"x":24,"y":12},{"v":0,"x":25,"y":12},{"v":0,"x":26,"y":12},{"v":0,"x":27,"y":12},{"v":0,"x":0,"y":13},{"v":0,"x":1,"y":13},{"v":0,"x":2,"y":13},{"v":0,"x":3,"y":13},{"v":0,"x":4,"y":13},{"v":0,"x":5,"y":13},{"v":0,"x":6,"y":13},{"v":0,"x":7,"y":13},{"v":0,"x":8,"y":13},{"v":0,"x":9,"y":13},{"v":0,"x":10,"y":13},{"v":0,"x":11,"y":13},{"v":0,"x":12,"y":13},{"v":110,"x":13,"y":13},{"v":121,"x":14,"y":13},{"v":122,"x":15,"y":13},{"v":121,"x":16,"y":13},{"v":202,"x":17,"y":13},{"v":252,"x":18,"y":13},{"v":194,"x":19,"y":13},{"v":3,"x":20,"y":13},{"v":0,"x":21,"y":13},{"v":0,"x":22,"y":13},{"v":0,"x":23,"y":13},{"v":0,"x":24,"y":13},{"v":0,"x":25,"y":13},{"v":0,"x":26,"y":13},{"v":0,"x":27,"y":13},{"v":0,"x":0,"y":14},{"v":0,"x":1,"y":14},{"v":0,"x":2,"y":14},{"v":0,"x":3,"y":14},{"v":0,"x":4,"y":14},{"v":0,"x":5,"y":14},{"v":0,"x":6,"y":14},{"v":0,"x":7,"y":14},{"v":0,"x":8,"y":14},{"v":0,"x":9,"y":14},{"v":10,"x":10,"y":14},{"v":53,"x":11,"y":14},{"v":179,"x":12,"y":14},{"v":253,"x":13,"y":14},{"v":253,"x":14,"y":14},{"v":255,"x":15,"y":14},{"v":253,"x":16,"y":14},{"v":253,"x":17,"y":14},{"v":228,"x":18,"y":14},{"v":35,"x":19,"y":14},{"v":0,"x":20,"y":14},{"v":0,"x":21,"y":14},{"v":0,"x":22,"y":14},{"v":0,"x":23,"y":14},{"v":0,"x":24,"y":14},{"v":0,"x":25,"y":14},{"v":0,"x":26,"y":14},{"v":0,"x":27,"y":14},{"v":0,"x":0,"y":15},{"v":0,"x":1,"y":15},{"v":0,"x":2,"y":15},{"v":0,"x":3,"y":15},{"v":0,"x":4,"y":15},{"v":0,"x":5,"y":15},{"v":0,"x":6,"y":15},{"v":0,"x":7,"y":15},{"v":5,"x":8,"y":15},{"v":54,"x":9,"y":15},{"v":227,"x":10,"y":15},{"v":252,"x":11,"y":15},{"v":243,"x":12,"y":15},{"v":228,"x":13,"y":15},{"v":170,"x":14,"y":15},{"v":242,"x":15,"y":15},{"v":252,"x":16,"y":15},{"v":252,"x":17,"y":15},{"v":231,"x":18,"y":15},{"v":117,"x":19,"y":15},{"v":6,"x":20,"y":15},{"v":0,"x":21,"y":15},{"v":0,"x":22,"y":15},{"v":0,"x":23,"y":15},{"v":0,"x":24,"y":15},{"v":0,"x":25,"y":15},{"v":0,"x":26,"y":15},{"v":0,"x":27,"y":15},{"v":0,"x":0,"y":16},{"v":0,"x":1,"y":16},{"v":0,"x":2,"y":16},{"v":0,"x":3,"y":16},{"v":0,"x":4,"y":16},{"v":0,"x":5,"y":16},{"v":0,"x":6,"y":16},{"v":6,"x":7,"y":16},{"v":78,"x":8,"y":16},{"v":252,"x":9,"y":16},{"v":252,"x":10,"y":16},{"v":125,"x":11,"y":16},{"v":59,"x":12,"y":16},{"v":0,"x":13,"y":16},{"v":18,"x":14,"y":16},{"v":208,"x":15,"y":16},{"v":252,"x":16,"y":16},{"v":252,"x":17,"y":16},{"v":252,"x":18,"y":16},{"v":252,"x":19,"y":16},{"v":87,"x":20,"y":16},{"v":7,"x":21,"y":16},{"v":0,"x":22,"y":16},{"v":0,"x":23,"y":16},{"v":0,"x":24,"y":16},{"v":0,"x":25,"y":16},{"v":0,"x":26,"y":16},{"v":0,"x":27,"y":16},{"v":0,"x":0,"y":17},{"v":0,"x":1,"y":17},{"v":0,"x":2,"y":17},{"v":0,"x":3,"y":17},{"v":0,"x":4,"y":17},{"v":0,"x":5,"y":17},{"v":5,"x":6,"y":17},{"v":135,"x":7,"y":17},{"v":252,"x":8,"y":17},{"v":252,"x":9,"y":17},{"v":180,"x":10,"y":17},{"v":16,"x":11,"y":17},{"v":0,"x":12,"y":17},{"v":21,"x":13,"y":17},{"v":203,"x":14,"y":17},{"v":253,"x":15,"y":17},{"v":247,"x":16,"y":17},{"v":129,"x":17,"y":17},{"v":173,"x":18,"y":17},{"v":252,"x":19,"y":17},{"v":252,"x":20,"y":17},{"v":184,"x":21,"y":17},{"v":66,"x":22,"y":17},{"v":49,"x":23,"y":17},{"v":49,"x":24,"y":17},{"v":0,"x":25,"y":17},{"v":0,"x":26,"y":17},{"v":0,"x":27,"y":17},{"v":0,"x":0,"y":18},{"v":0,"x":1,"y":18},{"v":0,"x":2,"y":18},{"v":0,"x":3,"y":18},{"v":0,"x":4,"y":18},{"v":3,"x":5,"y":18},{"v":136,"x":6,"y":18},{"v":252,"x":7,"y":18},{"v":241,"x":8,"y":18},{"v":106,"x":9,"y":18},{"v":17,"x":10,"y":18},{"v":0,"x":11,"y":18},{"v":53,"x":12,"y":18},{"v":200,"x":13,"y":18},{"v":252,"x":14,"y":18},{"v":216,"x":15,"y":18},{"v":65,"x":16,"y":18},{"v":0,"x":17,"y":18},{"v":14,"x":18,"y":18},{"v":72,"x":19,"y":18},{"v":163,"x":20,"y":18},{"v":241,"x":21,"y":18},{"v":252,"x":22,"y":18},{"v":252,"x":23,"y":18},{"v":223,"x":24,"y":18},{"v":0,"x":25,"y":18},{"v":0,"x":26,"y":18},{"v":0,"x":27,"y":18},{"v":0,"x":0,"y":19},{"v":0,"x":1,"y":19},{"v":0,"x":2,"y":19},{"v":0,"x":3,"y":19},{"v":0,"x":4,"y":19},{"v":105,"x":5,"y":19},{"v":252,"x":6,"y":19},{"v":242,"x":7,"y":19},{"v":88,"x":8,"y":19},{"v":18,"x":9,"y":19},{"v":73,"x":10,"y":19},{"v":170,"x":11,"y":19},{"v":244,"x":12,"y":19},{"v":252,"x":13,"y":19},{"v":126,"x":14,"y":19},{"v":29,"x":15,"y":19},{"v":0,"x":16,"y":19},{"v":0,"x":17,"y":19},{"v":0,"x":18,"y":19},{"v":0,"x":19,"y":19},{"v":0,"x":20,"y":19},{"v":89,"x":21,"y":19},{"v":180,"x":22,"y":19},{"v":180,"x":23,"y":19},{"v":37,"x":24,"y":19},{"v":0,"x":25,"y":19},{"v":0,"x":26,"y":19},{"v":0,"x":27,"y":19},{"v":0,"x":0,"y":20},{"v":0,"x":1,"y":20},{"v":0,"x":2,"y":20},{"v":0,"x":3,"y":20},{"v":0,"x":4,"y":20},{"v":231,"x":5,"y":20},{"v":252,"x":6,"y":20},{"v":245,"x":7,"y":20},{"v":205,"x":8,"y":20},{"v":216,"x":9,"y":20},{"v":252,"x":10,"y":20},{"v":252,"x":11,"y":20},{"v":252,"x":12,"y":20},{"v":124,"x":13,"y":20},{"v":3,"x":14,"y":20},{"v":0,"x":15,"y":20},{"v":0,"x":16,"y":20},{"v":0,"x":17,"y":20},{"v":0,"x":18,"y":20},{"v":0,"x":19,"y":20},{"v":0,"x":20,"y":20},{"v":0,"x":21,"y":20},{"v":0,"x":22,"y":20},{"v":0,"x":23,"y":20},{"v":0,"x":24,"y":20},{"v":0,"x":25,"y":20},{"v":0,"x":26,"y":20},{"v":0,"x":27,"y":20},{"v":0,"x":0,"y":21},{"v":0,"x":1,"y":21},{"v":0,"x":2,"y":21},{"v":0,"x":3,"y":21},{"v":0,"x":4,"y":21},{"v":207,"x":5,"y":21},{"v":252,"x":6,"y":21},{"v":252,"x":7,"y":21},{"v":252,"x":8,"y":21},{"v":252,"x":9,"y":21},{"v":178,"x":10,"y":21},{"v":116,"x":11,"y":21},{"v":36,"x":12,"y":21},{"v":4,"x":13,"y":21},{"v":0,"x":14,"y":21},{"v":0,"x":15,"y":21},{"v":0,"x":16,"y":21},{"v":0,"x":17,"y":21},{"v":0,"x":18,"y":21},{"v":0,"x":19,"y":21},{"v":0,"x":20,"y":21},{"v":0,"x":21,"y":21},{"v":0,"x":22,"y":21},{"v":0,"x":23,"y":21},{"v":0,"x":24,"y":21},{"v":0,"x":25,"y":21},{"v":0,"x":26,"y":21},{"v":0,"x":27,"y":21},{"v":0,"x":0,"y":22},{"v":0,"x":1,"y":22},{"v":0,"x":2,"y":22},{"v":0,"x":3,"y":22},{"v":0,"x":4,"y":22},{"v":13,"x":5,"y":22},{"v":93,"x":6,"y":22},{"v":143,"x":7,"y":22},{"v":121,"x":8,"y":22},{"v":23,"x":9,"y":22},{"v":6,"x":10,"y":22},{"v":0,"x":11,"y":22},{"v":0,"x":12,"y":22},{"v":0,"x":13,"y":22},{"v":0,"x":14,"y":22},{"v":0,"x":15,"y":22},{"v":0,"x":16,"y":22},{"v":0,"x":17,"y":22},{"v":0,"x":18,"y":22},{"v":0,"x":19,"y":22},{"v":0,"x":20,"y":22},{"v":0,"x":21,"y":22},{"v":0,"x":22,"y":22},{"v":0,"x":23,"y":22},{"v":0,"x":24,"y":22},{"v":0,"x":25,"y":22},{"v":0,"x":26,"y":22},{"v":0,"x":27,"y":22},{"v":0,"x":0,"y":23},{"v":0,"x":1,"y":23},{"v":0,"x":2,"y":23},{"v":0,"x":3,"y":23},{"v":0,"x":4,"y":23},{"v":0,"x":5,"y":23},{"v":0,"x":6,"y":23},{"v":0,"x":7,"y":23},{"v":0,"x":8,"y":23},{"v":0,"x":9,"y":23},{"v":0,"x":10,"y":23},{"v":0,"x":11,"y":23},{"v":0,"x":12,"y":23},{"v":0,"x":13,"y":23},{"v":0,"x":14,"y":23},{"v":0,"x":15,"y":23},{"v":0,"x":16,"y":23},{"v":0,"x":17,"y":23},{"v":0,"x":18,"y":23},{"v":0,"x":19,"y":23},{"v":0,"x":20,"y":23},{"v":0,"x":21,"y":23},{"v":0,"x":22,"y":23},{"v":0,"x":23,"y":23},{"v":0,"x":24,"y":23},{"v":0,"x":25,"y":23},{"v":0,"x":26,"y":23},{"v":0,"x":27,"y":23},{"v":0,"x":0,"y":24},{"v":0,"x":1,"y":24},{"v":0,"x":2,"y":24},{"v":0,"x":3,"y":24},{"v":0,"x":4,"y":24},{"v":0,"x":5,"y":24},{"v":0,"x":6,"y":24},{"v":0,"x":7,"y":24},{"v":0,"x":8,"y":24},{"v":0,"x":9,"y":24},{"v":0,"x":10,"y":24},{"v":0,"x":11,"y":24},{"v":0,"x":12,"y":24},{"v":0,"x":13,"y":24},{"v":0,"x":14,"y":24},{"v":0,"x":15,"y":24},{"v":0,"x":16,"y":24},{"v":0,"x":17,"y":24},{"v":0,"x":18,"y":24},{"v":0,"x":19,"y":24},{"v":0,"x":20,"y":24},{"v":0,"x":21,"y":24},{"v":0,"x":22,"y":24},{"v":0,"x":23,"y":24},{"v":0,"x":24,"y":24},{"v":0,"x":25,"y":24},{"v":0,"x":26,"y":24},{"v":0,"x":27,"y":24},{"v":0,"x":0,"y":25},{"v":0,"x":1,"y":25},{"v":0,"x":2,"y":25},{"v":0,"x":3,"y":25},{"v":0,"x":4,"y":25},{"v":0,"x":5,"y":25},{"v":0,"x":6,"y":25},{"v":0,"x":7,"y":25},{"v":0,"x":8,"y":25},{"v":0,"x":9,"y":25},{"v":0,"x":10,"y":25},{"v":0,"x":11,"y":25},{"v":0,"x":12,"y":25},{"v":0,"x":13,"y":25},{"v":0,"x":14,"y":25},{"v":0,"x":15,"y":25},{"v":0,"x":16,"y":25},{"v":0,"x":17,"y":25},{"v":0,"x":18,"y":25},{"v":0,"x":19,"y":25},{"v":0,"x":20,"y":25},{"v":0,"x":21,"y":25},{"v":0,"x":22,"y":25},{"v":0,"x":23,"y":25},{"v":0,"x":24,"y":25},{"v":0,"x":25,"y":25},{"v":0,"x":26,"y":25},{"v":0,"x":27,"y":25},{"v":0,"x":0,"y":26},{"v":0,"x":1,"y":26},{"v":0,"x":2,"y":26},{"v":0,"x":3,"y":26},{"v":0,"x":4,"y":26},{"v":0,"x":5,"y":26},{"v":0,"x":6,"y":26},{"v":0,"x":7,"y":26},{"v":0,"x":8,"y":26},{"v":0,"x":9,"y":26},{"v":0,"x":10,"y":26},{"v":0,"x":11,"y":26},{"v":0,"x":12,"y":26},{"v":0,"x":13,"y":26},{"v":0,"x":14,"y":26},{"v":0,"x":15,"y":26},{"v":0,"x":16,"y":26},{"v":0,"x":17,"y":26},{"v":0,"x":18,"y":26},{"v":0,"x":19,"y":26},{"v":0,"x":20,"y":26},{"v":0,"x":21,"y":26},{"v":0,"x":22,"y":26},{"v":0,"x":23,"y":26},{"v":0,"x":24,"y":26},{"v":0,"x":25,"y":26},{"v":0,"x":26,"y":26},{"v":0,"x":27,"y":26},{"v":0,"x":0,"y":27},{"v":0,"x":1,"y":27},{"v":0,"x":2,"y":27},{"v":0,"x":3,"y":27},{"v":0,"x":4,"y":27},{"v":0,"x":5,"y":27},{"v":0,"x":6,"y":27},{"v":0,"x":7,"y":27},{"v":0,"x":8,"y":27},{"v":0,"x":9,"y":27},{"v":0,"x":10,"y":27},{"v":0,"x":11,"y":27},{"v":0,"x":12,"y":27},{"v":0,"x":13,"y":27},{"v":0,"x":14,"y":27},{"v":0,"x":15,"y":27},{"v":0,"x":16,"y":27},{"v":0,"x":17,"y":27},{"v":0,"x":18,"y":27},{"v":0,"x":19,"y":27},{"v":0,"x":20,"y":27},{"v":0,"x":21,"y":27},{"v":0,"x":22,"y":27},{"v":0,"x":23,"y":27},{"v":0,"x":24,"y":27},{"v":0,"x":25,"y":27},{"v":0,"x":26,"y":27},{"v":0,"x":27,"y":27}]},"encoding":{"color":{"field":"v","legend":null,"scale":{"reverse":false,"scheme":"viridis"},"type":"quantitative"},"x":{"axis":null,"field":"x","type":"ordinal"},"y":{"axis":null,"field":"y","type":"ordinal"}},"height":200,"mark":"rect","width":200}

Below we use Tucan.concat/2 to plot a grid of 40 images of the MNIST dataset. We also set a grayscale color scheme.

mnist_path = Path.expand("../../assets/mnist_sample.bin", __DIR__)
images = File.read!(mnist_path) |> Nx.deserialize()

images =
  for i <- 1..40 do
    image = images[[images: i]]
    Tucan.imshow(image, width: 60, height: 60, color_scheme: :greys, reverse: true)
  end

Tucan.concat(images, columns: 10)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","columns":10,"concat":[{"data":{"values":[{"v":0,"x":0,"y":0},{"v":0,"x":1,"y":0},{"v":0,"x":2,"y":0},{"v":0,"x":3,"y":0},{"v":0,"x":4,"y":0},{"v":0,"x":5,"y":0},{"v":0,"x":6,"y":0},{"v":0,"x":7,"y":0},{"v":0,"x":8,"y":0},{"v":0,"x":9,"y":0},{"v":0,"x":10,"y":0},{"v":0,"x":11,"y":0},{"v":0,"x":12,"y":0},{"v":0,"x":13,"y":0},{"v":0,"x":14,"y":0},{"v":0,"x":15,"y":0},{"v":0,"x":16,"y":0},{"v":0,"x":17,"y":0},{"v":0,"x":18,"y":0},{"v":0,"x":19,"y":0},{"v":0,"x":20,"y":0},{"v":0,"x":21,"y":0},{"v":0,"x":22,"y":0},{"v":0,"x":23,"y":0},{"v":0,"x":24,"y":0},{"v":0,"x":25,"y":0},{"v":0,"x":26,"y":0},{"v":0,"x":27,"y":0},{"v":0,"x":0,"y":1},{"v":0,"x":1,"y":1},{"v":0,"x":2,"y":1},{"v":0,"x":3,"y":1},{"v":0,"x":4,"y":1},{"v":0,"x":5,"y":1},{"v":0,"x":6,"y":1},{"v":0,"x":7,"y":1},{"v":0,"x":8,"y":1},{"v":0,"x":9,"y":1},{"v":0,"x":10,"y":1},{"v":0,"x":11,"y":1},{"v":0,"x":12,"y":1},{"v":0,"x":13,"y":1},{"v":0,"x":14,"y":1},{"v":0,"x":15,"y":1},{"v":0,"x":16,"y":1},{"v":0,"x":17,"y":1},{"v":0,"x":18,"y":1},{"v":0,"x":19,"y":1},{"v":0,"x":20,"y":1},{"v":0,"x":21,"y":1},{"v":0,"x":22,"y":1},{"v":0,"x":23,"y":1},{"v":0,"x":24,"y":1},{"v":0,"x":25,"y":1},{"v":0,"x":26,"y":1},{"v":0,"x":27,"y":1},{"v":0,"x":0,"y":2},{"v":0,"x":1,"y":2},{"v":0,"x":2,"y":2},{"v":0,"x":3,"y":2},{"v":0,"x":4,"y":2},{"v":0,"x":5,"y":2},{"v":0,"x":6,"y":2},{"v":0,"x":7,"y":2},{"v":0,"x":8,"y":2},{"v":0,"x":9,"y":2},{"v":0,"x":10,"y":2},{"v":0,"x":11,"y":2},{"v":0,"x":12,"y":2},{"v":0,"x":13,"y":2},{"v":0,"x":14,"y":2},{"v":0,"x":15,"y":2},{"v":0,"x":16,"y":2},{"v":0,"x":17,"y":2},{"v":0,"x":18,"y":2},{"v":0,"x":19,"y":2},{"v":0,"x":20,"y":2},{"v":0,"x":21,"y":2},{"v":0,"x":22,"y":2},{"v":0,"x":23,"y":2},{"v":0,"x":24,"y":2},{"v":0,"x":25,"y":2},{"v":0,"x":26,"y":2},{"v":0,"x":27,"y":2},{"v":0,"x":0,"y":3},{"v":0,"x":1,"y":3},{"v":0,"x":2,"y":3},{"v":0,"x":3,"y":3},{"v":0,"x":4,"y":3},{"v":0,"x":5,"y":3},{"v":0,"x":6,"y":3},{"v":0,"x":7,"y":3},{"v":0,"x":8,"y":3},{"v":0,"x":9,"y":3},{"v":0,"x":10,"y":3},{"v":0,"x":11,"y":3},{"v":0,"x":12,"y":3},{"v":0,"x":13,"y":3},{"v":0,"x":14,"y":3},{"v":0,"x":15,"y":3},{"v":0,"x":16,"y":3},{"v":0,"x":17,"y":3},{"v":0,"x":18,"y":3},{"v":0,"x":19,"y":3},{"v":0,"x":20,"y":3},{"v":0,"x":21,"y":3},{"v":0,"x":22,"y":3},{"v":0,"x":23,"y":3},{"v":0,"x":24,"y":3},{"v":0,"x":25,"y":3},{"v":0,"x":26,"y":3},{"v":0,"x":27,"y":3},{"v":0,"x":0,"y":4},{"v":0,"x":1,"y":4},{"v":0,"x":2,"y":4},{"v":0,"x":3,"y":4},{"v":0,"x":4,"y":4},{"v":0,"x":5,"y":4},{"v":0,"x":6,"y":4},{"v":0,"x":7,"y":4},{"v":0,"x":8,"y":4},{"v":0,"x":9,"y":4},{"v":0,"x":10,"y":4},{"v":0,"x":11,"y":4},{"v":0,"x":12,"y":4},{"v":0,"x":13,"y":4},{"v":0,"x":14,"y":4},{"v":51,"x":15,"y":4},{"v":159,"x":16,"y":4},{"v":253,"x":17,"y":4},{"v":159,"x":18,"y":4},{"v":50,"x":19,"y":4},{"v":0,"x":20,"y":4},{"v":0,"x":21,"y":4},{"v":0,"x":22,"y":4},{"v":0,"x":23,"y":4},{"v":0,"x":24,"y":4},{"v":0,"x":25,"y":4},{"v":0,"x":26,"y":4},{"v":0,"x":27,"y":4},{"v":0,"x":0,"y":5},{"v":0,"x":1,"y":5},{"v":0,"x":2,"y":5},{"v":0,"x":3,"y":5},{"v":0,"x":4,"y":5},{"v":0,"x":5,"y":5},{"v":0,"x":6,"y":5},{"v":0,"x":7,"y":5},{"v":0,"x":8,"y":5},{"v":0,"x":9,"y":5},{"v":0,"x":10,"y":5},{"v":0,"x":11,"y":5},{"v":0,"x":12,"y":5},{"v":0,"x":13,"y":5},{"v":48,"x":14,"y":5},{"v":238,"x":15,"y":5},{"v":252,"x":16,"y":5},{"v":252,"x":17,"y":5},{"v":252,"x":18,"y":5},{"v":237,"x":19,"y":5},{"v":0,"x":20,"y":5},{"v":0,"x":21,"y":5},{"v":0,"x":22,"y":5},{"v":0,"x":23,"y":5},{"v":0,"x":24,"y":5},{"v":0,"x":25,"y":5},{"v":0,"x":26,"y":5},{"v":0,"x":27,"y":5},{"v":0,"x":0,"y":6},{"v":0,"x":1,"y":6},{"v":0,"x":2,"y":6},{"v":0,"x":3,"y":6},{"v":0,"x":4,"y":6},{"v":0,"x":5,"y":6},{"v":0,"x":6,"y":6},{"v":0,"x":7,"y":6},{"v":0,"x":8,"y":6},{"v":0,"x":9,"y":6},{"v":0,"x":10,"y":6},{"v":0,"x":11,"y":6},{"v":0,"x":12,"y":6},{"v":54,"x":13,"y":6},{"v":227,"x":14,"y":6},{"v":253,"x":15,"y":6},{"v":252,"x":16,"y":6},{"v":239,"x":17,"y":6},{"v":233,"x":18,"y":6},{"v":252,"x":19,"y":6},{"v":57,"x":20,"y":6},{"v":6,"x":21,"y":6},{"v":0,"x":22,"y":6},{"v":0,"x":23,"y":6},{"v":0,"x":24,"y":6},{"v":0,"x":25,"y":6},{"v":0,"x":26,"y":6},{"v":0,"x":27,"y":6},{"v":0,"x":0,"y":7},{"v":0,"x":1,"y":7},{"v":0,"x":2,"y":7},{"v":0,"x":3,"y":7},{"v":0,"x":4,"y":7},{"v":0,"x":5,"y":7},{"v":0,"x":6,"y":7},{"v":0,"x":7,"y":7},{"v":0,"x":8,"y":7},{"v":0,"x":9,"y":7},{"v":0,"x":10,"y":7},{"v":10,"x":11,"y":7},{"v":60,"x":12,"y":7},{"v":224,"x":13,"y":7},{"v":252,"x":14,"y":7},{"v":253,"x":15,"y":7},{"v":252,"x":16,"y":7},{"v":202,"x":17,"y":7},{"v":84,"x":18,"y":7},{"v":252,"x":19,"y":7},{"v":253,"x":20,"y":7},{"v":122,"x":21,"y":7},{"v":0,"x":22,"y":7},{"v":0,"x":23,"y":7},{"v":0,"x":24,"y":7},{"v":0,"x":25,"y":7},{"v":0,"x":26,"y":7},{"v":0,"x":27,"y":7},{"v":0,"x":0,"y":8},{"v":0,"x":1,"y":8},{"v":0,"x":2,"y":8},{"v":0,"x":3,"y":8},{"v":0,"x":4,"y":8},{"v":0,"x":5,"y":8},{"v":0,"x":6,"y":8},{"v":0,"x":7,"y":8},{"v":0,"x":8,"y":8},{"v":0,"x":9,"y":8},{"v":0,"x":10,"y":8},{"v":163,"x":11,"y":8},{"v":252,"x":12,"y":8},{"v":252,"x":13,"y":8},{"v":252,"x":14,"y":8},{"v":253,"x":15,"y":8},{"v":252,"x":16,"y":8},{"v":252,"x":17,"y":8},{"v":96,"x":18,"y":8},{"v":189,"x":19,"y":8},{"v":253,"x":20,"y":8},{"v":167,"x":21,"y":8},{"v":0,"x":22,"y":8},{"v":0,"x":23,"y":8},{"v":0,"x":24,"y":8},{"v":0,"x":25,"y":8},{"v":0,"x":26,"y":8},{"v":0,"x":27,"y":8},{"v":0,"x":0,"y":9},{"v":0,"x":1,"y":9},{"v":0,"x":2,"y":9},{"v":0,"x":3,"y":9},{"v":0,"x":4,"y":9},{"v":0,"x":5,"y":9},{"v":0,"x":6,"y":9},{"v":0,"x":7,"y":9},{"v":0,"x":8,"y":9},{"v":0,"x":9,"y":9},{"v":51,"x":10,"y":9},{"v":238,"x":11,"y":9},{"v":253,"x":12,"y":9},{"v":253,"x":13,"y":9},{"v":190,"x":14,"y":9},{"v":114,"x":15,"y":9},{"v":253,"x":16,"y":9},{"v":228,"x":17,"y":9},{"v":47,"x":18,"y":9},{"v":79,"x":19,"y":9},{"v":255,"x":20,"y":9},{"v":168,"x":21,"y":9},{"v":0,"x":22,"y":9},{"v":0,"x":23,"y":9},{"v":0,"x":24,"y":9},{"v":0,"x":25,"y":9},{"v":0,"x":26,"y":9},{"v":0,"x":27,"y":9},{"v":0,"x":0,"y":10},{"v":0,"x":1,"y":10},{"v":0,"x":2,"y":10},{"v":0,"x":3,"y":10},{"v":0,"x":4,"y":10},{"v":0,"x":5,"y":10},{"v":0,"x":6,"y":10},{"v":0,"x":7,"y":10},{"v":0,"x":8,"y":10},{"v":48,"x":9,"y":10},{"v":238,"x":10,"y":10},{"v":252,"x":11,"y":10},{"v":252,"x":12,"y":10},{"v":179,"x":13,"y":10},{"v":12,"x":14,"y":10},{"v":75,"x":15,"y":10},{"v":121,"x":16,"y":10},{"v":21,"x":17,"y":10},{"v":0,"x":18,"y":10},{"v":0,"x":19,"y":10},{"v":253,"x":20,"y":10},{"v":243,"x":21,"y":10},{"v":50,"x":22,"y":10},{"v":0,"x":23,"y":10},{"v":0,"x":24,"y":10},{"v":0,"x":25,"y":10},{"v":0,"x":26,"y":10},{"v":0,"x":27,"y":10},{"v":0,"x":0,"y":11},{"v":0,"x":1,"y":11},{"v":0,"x":2,"y":11},{"v":0,"x":3,"y":11},{"v":0,"x":4,"y":11},{"v":0,"x":5,"y":11},{"v":0,"x":6,"y":11},{"v":0,"x":7,"y":11},{"v":38,"x":8,"y":11},{"v":165,"x":9,"y":11},{"v":253,"x":10,"y":11},{"v":233,"x":11,"y":11},{"v":208,"x":12,"y":11},{"v":84,"x":13,"y":11},{"v":0,"x":14,"y":11},{"v":0,"x":15,"y":11},{"v":0,"x":16,"y":11},{"v":0,"x":17,"y":11},{"v":0,"x":18,"y":11},{"v":0,"x":19,"y":11},{"v":253,"x":20,"y":11},{"v":252,"x":21,"y":11},{"v":165,"x":22,"y":11},{"v":0,"x":23,"y":11},{"v":0,"x":24,"y":11},{"v":0,"x":25,"y":11},{"v":0,"x":26,"y":11},{"v":0,"x":27,"y":11},{"v":0,"x":0,"y":12},{"v":0,"x":1,"y":12},{"v":0,"x":2,"y":12},{"v":0,"x":3,"y":12},{"v":0,"x":4,"y":12},{"v":0,"x":5,"y":12},{"v":0,"x":6,"y":12},{"v":7,"x":7,"y":12},{"v":178,"x":8,"y":12},{"v":252,"x":9,"y":12},{"v":240,"x":10,"y":12},{"v":71,"x":11,"y":12},{"v":19,"x":12,"y":12},{"v":28,"x":13,"y":12},{"v":0,"x":14,"y":12},{"v":0,"x":15,"y":12},{"v":0,"x":16,"y":12},{"v":0,"x":17,"y":12},{"v":0,"x":18,"y":12},{"v":0,"x":19,"y":12},{"v":253,"x":20,"y":12},{"v":252,"x":21,"y":12},{"v":195,"x":22,"y":12},{"v":0,"x":23,"y":12},{"v":0,"x":24,"y":12},{"v":0,"x":25,"y":12},{"v":0,"x":26,"y":12},{"v":0,"x":27,"y":12},{"v":0,"x":0,"y":13},{"v":0,"x":1,"y":13},{"v":0,"x":2,"y":13},{"v":0,"x":3,"y":13},{"v":0,"x":4,"y":13},{"v":0,"x":5,"y":13},{"v":0,"x":6,"y":13},{"v":57,"x":7,"y":13},{"v":252,"x":8,"y":13},{"v":252,"x":9,"y":13},{"v":63,"x":10,"y":13},{"v":0,"x":11,"y":13},{"v":0,"x":12,"y":13},{"v":0,"x":13,"y":13},{"v":0,"x":14,"y":13},{"v":0,"x":15,"y":13},{"v":0,"x":16,"y":13},{"v":0,"x":17,"y":13},{"v":0,"x":18,"y":13},{"v":0,"x":19,"y":13},{"v":253,"x":20,"y":13},{"v":252,"x":21,"y":13},{"v":195,"x":22,"y":13},{"v":0,"x":23,"y":13},{"v":0,"x":24,"y":13},{"v":0,"x":25,"y":13},{"v":0,"x":26,"y":13},{"v":0,"x":27,"y":13},{"v":0,"x":0,"y":14},{"v":0,"x":1,"y":14},{"v":0,"x":2,"y":14},{"v":0,"x":3,"y":14},{"v":0,"x":4,"y":14},{"v":0,"x":5,"y":14},{"v":0,"x":6,"y":14},{"v":198,"x":7,"y":14},{"v":253,"x":8,"y":14},{"v":190,"x":9,"y":14},{"v":0,"x":10,"y":14},{"v":0,"x":11,"y":14},{"v":0,"x":12,"y":14},{"v":0,"x":13,"y":14},{"v":0,"x":14,"y":14},{"v":0,"x":15,"y":14},{"v":0,"x":16,"y":14},{"v":0,"x":17,"y":14},{"v":0,"x":18,"y":14},{"v":0,"x":19,"y":14},{"v":255,"x":20,"y":14},{"v":253,"x":21,"y":14},{"v":196,"x":22,"y":14},{"v":0,"x":23,"y":14},{"v":0,"x":24,"y":14},{"v":0,"x":25,"y":14},{"v":0,"x":26,"y":14},{"v":0,"x":27,"y":14},{"v":0,"x":0,"y":15},{"v":0,"x":1,"y":15},{"v":0,"x":2,"y":15},{"v":0,"x":3,"y":15},{"v":0,"x":4,"y":15},{"v":0,"x":5,"y":15},{"v":76,"x":6,"y":15},{"v":246,"x":7,"y":15},{"v":252,"x":8,"y":15},{"v":112,"x":9,"y":15},{"v":0,"x":10,"y":15},{"v":0,"x":11,"y":15},{"v":0,"x":12,"y":15},{"v":0,"x":13,"y":15},{"v":0,"x":14,"y":15},{"v":0,"x":15,"y":15},{"v":0,"x":16,"y":15},{"v":0,"x":17,"y":15},{"v":0,"x":18,"y":15},{"v":0,"x":19,"y":15},{"v":253,"x":20,"y":15},{"v":252,"x":21,"y":15},{"v":148,"x":22,"y":15},{"v":0,"x":23,"y":15},{"v":0,"x":24,"y":15},{"v":0,"x":25,"y":15},{"v":0,"x":26,"y":15},{"v":0,"x":27,"y":15},{"v":0,"x":0,"y":16},{"v":0,"x":1,"y":16},{"v":0,"x":2,"y":16},{"v":0,"x":3,"y":16},{"v":0,"x":4,"y":16},{"v":0,"x":5,"y":16},{"v":85,"x":6,"y":16},{"v":252,"x":7,"y":16},{"v":230,"x":8,"y":16},{"v":25,"x":9,"y":16},{"v":0,"x":10,"y":16},{"v":0,"x":11,"y":16},{"v":0,"x":12,"y":16},{"v":0,"x":13,"y":16},{"v":0,"x":14,"y":16},{"v":0,"x":15,"y":16},{"v":0,"x":16,"y":16},{"v":0,"x":17,"y":16},{"v":7,"x":18,"y":16},{"v":135,"x":19,"y":16},{"v":253,"x":20,"y":16},{"v":186,"x":21,"y":16},{"v":12,"x":22,"y":16},{"v":0,"x":23,"y":16},{"v":0,"x":24,"y":16},{"v":0,"x":25,"y":16},{"v":0,"x":26,"y":16},{"v":0,"x":27,"y":16},{"v":0,"x":0,"y":17},{"v":0,"x":1,"y":17},{"v":0,"x":2,"y":17},{"v":0,"x":3,"y":17},{"v":0,"x":4,"y":17},{"v":0,"x":5,"y":17},{"v":85,"x":6,"y":17},{"v":252,"x":7,"y":17},{"v":223,"x":8,"y":17},{"v":0,"x":9,"y":17},{"v":0,"x":10,"y":17},{"v":0,"x":11,"y":17},{"v":0,"x":12,"y":17},{"v":0,"x":13,"y":17},{"v":0,"x":14,"y":17},{"v":0,"x":15,"y":17},{"v":0,"x":16,"y":17},{"v":7,"x":17,"y":17},{"v":131,"x":18,"y":17},{"v":252,"x":19,"y":17},{"v":225,"x":20,"y":17},{"v":71,"x":21,"y":17},{"v":0,"x":22,"y":17},{"v":0,"x":23,"y":17},{"v":0,"x":24,"y":17},{"v":0,"x":25,"y":17},{"v":0,"x":26,"y":17},{"v":0,"x":27,"y":17},{"v":0,"x":0,"y":18},{"v":0,"x":1,"y":18},{"v":0,"x":2,"y":18},{"v":0,"x":3,"y":18},{"v":0,"x":4,"y":18},{"v":0,"x":5,"y":18},{"v":85,"x":6,"y":18},{"v":252,"x":7,"y":18},{"v":145,"x":8,"y":18},{"v":0,"x":9,"y":18},{"v":0,"x":10,"y":18},{"v":0,"x":11,"y":18},{"v":0,"x":12,"y":18},{"v":0,"x":13,"y":18},{"v":0,"x":14,"y":18},{"v":0,"x":15,"y":18},{"v":48,"x":16,"y":18},{"v":165,"x":17,"y":18},{"v":252,"x":18,"y":18},{"v":173,"x":19,"y":18},{"v":0,"x":20,"y":18},{"v":0,"x":21,"y":18},{"v":0,"x":22,"y":18},{"v":0,"x":23,"y":18},{"v":0,"x":24,"y":18},{"v":0,"x":25,"y":18},{"v":0,"x":26,"y":18},{"v":0,"x":27,"y":18},{"v":0,"x":0,"y":19},{"v":0,"x":1,"y":19},{"v":0,"x":2,"y":19},{"v":0,"x":3,"y":19},{"v":0,"x":4,"y":19},{"v":0,"x":5,"y":19},{"v":86,"x":6,"y":19},{"v":253,"x":7,"y":19},{"v":225,"x":8,"y":19},{"v":0,"x":9,"y":19},{"v":0,"x":10,"y":19},{"v":0,"x":11,"y":19},{"v":0,"x":12,"y":19},{"v":0,"x":13,"y":19},{"v":0,"x":14,"y":19},{"v":114,"x":15,"y":19},{"v":238,"x":16,"y":19},{"v":253,"x":17,"y":19},{"v":162,"x":18,"y":19},{"v":0,"x":19,"y":19},{"v":0,"x":20,"y":19},{"v":0,"x":21,"y":19},{"v":0,"x":22,"y":19},{"v":0,"x":23,"y":19},{"v":0,"x":24,"y":19},{"v":0,"x":25,"y":19},{"v":0,"x":26,"y":19},{"v":0,"x":27,"y":19},{"v":0,"x":0,"y":20},{"v":0,"x":1,"y":20},{"v":0,"x":2,"y":20},{"v":0,"x":3,"y":20},{"v":0,"x":4,"y":20},{"v":0,"x":5,"y":20},{"v":85,"x":6,"y":20},{"v":252,"x":7,"y":20},{"v":249,"x":8,"y":20},{"v":146,"x":9,"y":20},{"v":48,"x":10,"y":20},{"v":29,"x":11,"y":20},{"v":85,"x":12,"y":20},{"v":178,"x":13,"y":20},{"v":225,"x":14,"y":20},{"v":253,"x":15,"y":20},{"v":223,"x":16,"y":20},{"v":167,"x":17,"y":20},{"v":56,"x":18,"y":20},{"v":0,"x":19,"y":20},{"v":0,"x":20,"y":20},{"v":0,"x":21,"y":20},{"v":0,"x":22,"y":20},{"v":0,"x":23,"y":20},{"v":0,"x":24,"y":20},{"v":0,"x":25,"y":20},{"v":0,"x":26,"y":20},{"v":0,"x":27,"y":20},{"v":0,"x":0,"y":21},{"v":0,"x":1,"y":21},{"v":0,"x":2,"y":21},{"v":0,"x":3,"y":21},{"v":0,"x":4,"y":21},{"v":0,"x":5,"y":21},{"v":85,"x":6,"y":21},{"v":252,"x":7,"y":21},{"v":252,"x":8,"y":21},{"v":252,"x":9,"y":21},{"v":229,"x":10,"y":21},{"v":215,"x":11,"y":21},{"v":252,"x":12,"y":21},{"v":252,"x":13,"y":21},{"v":252,"x":14,"y":21},{"v":196,"x":15,"y":21},{"v":130,"x":16,"y":21},{"v":0,"x":17,"y":21},{"v":0,"x":18,"y":21},{"v":0,"x":19,"y":21},{"v":0,"x":20,"y":21},{"v":0,"x":21,"y":21},{"v":0,"x":22,"y":21},{"v":0,"x":23,"y":21},{"v":0,"x":24,"y":21},{"v":0,"x":25,"y":21},{"v":0,"x":26,"y":21},{"v":0,"x":27,"y":21},{"v":0,"x":0,"y":22},{"v":0,"x":1,"y":22},{"v":0,"x":2,"y":22},{"v":0,"x":3,"y":22},{"v":0,"x":4,"y":22},{"v":0,"x":5,"y":22},{"v":28,"x":6,"y":22},{"v":199,"x":7,"y":22},{"v":252,"x":8,"y":22},{"v":252,"x":9,"y":22},{"v":253,"x":10,"y":22},{"v":252,"x":11,"y":22},{"v":252,"x":12,"y":22},{"v":233,"x":13,"y":22},{"v":145,"x":14,"y":22},{"v":0,"x":15,"y":22},{"v":0,"x":16,"y":22},{"v":0,"x":17,"y":22},{"v":0,"x":18,"y":22},{"v":0,"x":19,"y":22},{"v":0,"x":20,"y":22},{"v":0,"x":21,"y":22},{"v":0,"x":22,"y":22},{"v":0,"x":23,"y":22},{"v":0,"x":24,"y":22},{"v":0,"x":25,"y":22},{"v":0,"x":26,"y":22},{"v":0,"x":27,"y":22},{"v":0,"x":0,"y":23},{"v":0,"x":1,"y":23},{"v":0,"x":2,"y":23},{"v":0,"x":3,"y":23},{"v":0,"x":4,"y":23},{"v":0,"x":5,"y":23},{"v":0,"x":6,"y":23},{"v":25,"x":7,"y":23},{"v":128,"x":8,"y":23},{"v":252,"x":9,"y":23},{"v":253,"x":10,"y":23},{"v":252,"x":11,"y":23},{"v":141,"x":12,"y":23},{"v":37,"x":13,"y":23},{"v":0,"x":14,"y":23},{"v":0,"x":15,"y":23},{"v":0,"x":16,"y":23},{"v":0,"x":17,"y":23},{"v":0,"x":18,"y":23},{"v":0,"x":19,"y":23},{"v":0,"x":20,"y":23},{"v":0,"x":21,"y":23},{"v":0,"x":22,"y":23},{"v":0,"x":23,"y":23},{"v":0,"x":24,"y":23},{"v":0,"x":25,"y":23},{"v":0,"x":26,"y":23},{"v":0,"x":27,"y":23},{"v":0,"x":0,"y":24},{"v":0,"x":1,"y":24},{"v":0,"x":2,"y":24},{"v":0,"x":3,"y":24},{"v":0,"x":4,"y":24},{"v":0,"x":5,"y":24},{"v":0,"x":6,"y":24},{"v":0,"x":7,"y":24},{"v":0,"x":8,"y":24},{"v":0,"x":9,"y":24},{"v":0,"x":10,"y":24},{"v":0,"x":11,"y":24},{"v":0,"x":12,"y":24},{"v":0,"x":13,"y":24},{"v":0,"x":14,"y":24},{"v":0,"x":15,"y":24},{"v":0,"x":16,"y":24},{"v":0,"x":17,"y":24},{"v":0,"x":18,"y":24},{"v":0,"x":19,"y":24},{"v":0,"x":20,"y":24},{"v":0,"x":21,"y":24},{"v":0,"x":22,"y":24},{"v":0,"x":23,"y":24},{"v":0,"x":24,"y":24},{"v":0,"x":25,"y":24},{"v":0,"x":26,"y":24},{"v":0,"x":27,"y":24},{"v":0,"x":0,"y":25},{"v":0,"x":1,"y":25},{"v":0,"x":2,"y":25},{"v":0,"x":3,"y":25},{"v":0,"x":4,"y":25},{"v":0,"x":5,"y":25},{"v":0,"x":6,"y":25},{"v":0,"x":7,"y":25},{"v":0,"x":8,"y":25},{"v":0,"x":9,"y":25},{"v":0,"x":10,"y":25},{"v":0,"x":11,"y":25},{"v":0,"x":12,"y":25},{"v":0,"x":13,"y":25},{"v":0,"x":14,"y":25},{"v":0,"x":15,"y":25},{"v":0,"x":16,"y":25},{"v":0,"x":17,"y":25},{"v":0,"x":18,"y":25},{"v":0,"x":19,"y":25},{"v":0,"x":20,"y":25},{"v":0,"x":21,"y":25},{"v":0,"x":22,"y":25},{"v":0,"x":23,"y":25},{"v":0,"x":24,"y":25},{"v":0,"x":25,"y":25},{"v":0,"x":26,"y":25},{"v":0,"x":27,"y":25},{"v":0,"x":0,"y":26},{"v":0,"x":1,"y":26},{"v":0,"x":2,"y":26},{"v":0,"x":3,"y":26},{"v":0,"x":4,"y":26},{"v":0,"x":5,"y":26},{"v":0,"x":6,"y":26},{"v":0,"x":7,"y":26},{"v":0,"x":8,"y":26},{"v":0,"x":9,"y":26},{"v":0,"x":10,"y":26},{"v":0,"x":11,"y":26},{"v":0,"x":12,"y":26},{"v":0,"x":13,"y":26},{"v":0,"x":14,"y":26},{"v":0,"x":15,"y":26},{"v":0,"x":16,"y":26},{"v":0,"x":17,"y":26},{"v":0,"x":18,"y":26},{"v":0,"x":19,"y":26},{"v":0,"x":20,"y":26},{"v":0,"x":21,"y":26},{"v":0,"x":22,"y":26},{"v":0,"x":23,"y":26},{"v":0,"x":24,"y":26},{"v":0,"x":25,"y":26},{"v":0,"x":26,"y":26},{"v":0,"x":27,"y":26},{"v":0,"x":0,"y":27},{"v":0,"x":1,"y":27},{"v":0,"x":2,"y":27},{"v":0,"x":3,"y":27},{"v":0,"x":4,"y":27},{"v":0,"x":5,"y":27},{"v":0,"x":6,"y":27},{"v":0,"x":7,"y":27},{"v":0,"x":8,"y":27},{"v":0,"x":9,"y":27},{"v":0,"x":10,"y":27},{"v":0,"x":11,"y":27},{"v":0,"x":12,"y":27},{"v":0,"x":13,"y":27},{"v":0,"x":14,"y":27},{"v":0,"x":15,"y":27},{"v":0,"x":16,"y":27},{"v":0,"x":17,"y":27},{"v":0,"x":18,"y":27},{"v":0,"x":19,"y":27},{"v":0,"x":20,"y":27},{"v":0,"x":21,"y":27},{"v":0,"x":22,"y":27},{"v":0,"x":23,"y":27},{"v":0,"x":24,"y":27},{"v":0,"x":25,"y":27},{"v":0,"x":26,"y":27},{"v":0,"x":27,"y":27}]},"encoding":{"color":{"field":"v","legend":null,"scale":{"reverse":true,"scheme":"greys"},"type":"quantitative"},"x":{"axis":null,"field":"x","type":"ordinal"},"y":{"axis":null,"field":"y","type":"ordinal"}},"height":60,"mark":"rect","width":60},{"data":{"values":[{"v":0,"x":0,"y":0},{"v":0,"x":1,"y":0},{"v":0,"x":2,"y":0},{"v":0,"x":3,"y":0},{"v":0,"x":4,"y":0},{"v":0,"x":5,"y":0},{"v":0,"x":6,"y":0},{"v":0,"x":7,"y":0},{"v":0,"x":8,"y":0},{"v":0,"x":9,"y":0},{"v":0,"x":10,"y":0},{"v":0,"x":11,"y":0},{"v":0,"x":12,"y":0},{"v":0,"x":13,"y":0},{"v":0,"x":14,"y":0},{"v":0,"x":15,"y":0},{"v":0,"x":16,"y":0},{"v":0,"x":17,"y":0},{"v":0,"x":18,"y":0},{"v":0,"x":19,"y":0},{"v":0,"x":20,"y":0},{"v":0,"x":21,"y":0},{"v":0,"x":22,"y":0},{"v":0,"x":23,"y":0},{"v":0,"x":24,"y":0},{"v":0,"x":25,"y":0},{"v":0,"x":26,"y":0},{"v":0,"x":27,"y":0},{"v":0,"x":0,"y":1},{"v":0,"x":1,"y":1},{"v":0,"x":2,"y":1},{"v":0,"x":3,"y":1},{"v":0,"x":4,"y":1},{"v":0,"x":5,"y":1},{"v":0,"x":6,"y":1},{"v":0,"x":7,"y":1},{"v":0,"x":8,"y":1},{"v":0,"x":9,"y":1},{"v":0,"x":10,"y":1},{"v":0,"x":11,"y":1},{"v":0,"x":12,"y":1},{"v":0,"x":13,"y":1},{"v":0,"x":14,"y":1},{"v":0,"x":15,"y":1},{"v":0,"x":16,"y":1},{"v":0,"x":17,"y":1},{"v":0,"x":18,"y":1},{"v":0,"x":19,"y":1},{"v":0,"x":20,"y":1},{"v":0,"x":21,"y":1},{"v":0,"x":22,"y":1},{"v":0,"x":23,"y":1},{"v":0,"x":24,"y":1},{"v":0,"x":25,"y":1},{"v":0,"x":26,"y":1},{"v":0,"x":27,"y":1},{"v":0,"x":0,"y":2},{"v":0,"x":1,"y":2},{"v":0,"x":2,"y":2},{"v":0,"x":3,"y":2},{"v":0,"x":4,"y":2},{"v":0,"x":5,"y":2},{"v":0,"x":6,"y":2},{"v":0,"x":7,"y":2},{"v":0,"x":8,"y":2},{"v":0,"x":9,"y":2},{"v":0,"x":10,"y":2},{"v":0,"x":11,"y":2},{"v":0,"x":12,"y":2},{"v":0,"x":13,"y":2},{"v":0,"x":14,"y":2},{"v":0,"x":15,"y":2},{"v":0,"x":16,"y":2},{"v":0,"x":17,"y":2},{"v":0,"x":18,"y":2},{"v":0,"x":19,"y":2},{"v":0,"x":20,"y":2},{"v":0,"x":21,"y":2},{"v":0,"x":22,"y":2},{"v":0,"x":23,"y":2},{"v":0,"x":24,"y":2},{"v":0,"x":25,"y":2},{"v":0,"x":26,"y":2},{"v":0,"x":27,"y":2},{"v":0,"x":0,"y":3},{"v":0,"x":1,"y":3},{"v":0,"x":2,"y":3},{"v":0,"x":3,"y":3},{"v":0,"x":4,"y":3},{"v":0,"x":5,"y":3},{"v":0,"x":6,"y":3},{"v":0,"x":7,"y":3},{"v":0,"x":8,"y":3},{"v":0,"x":9,"y":3},{"v":0,"x":10,"y":3},{"v":0,"x":11,"y":3},{"v":0,"x":12,"y":3},{"v":0,"x":13,"y":3},{"v":0,"x":14,"y":3},{"v":0,"x":15,"y":3},{"v":0,"x":16,"y":3},{"v":0,"x":17,"y":3},{"v":0,"x":18,"y":3},{"v":0,"x":19,"y":3},{"v":0,"x":20,"y":3},{"v":0,"x":21,"y":3},{"v":0,"x":22,"y":3},{"v":0,"x":23,"y":3},{"v":0,"x":24,"y":3},{"v":0,"x":25,"y":3},{"v":0,"x":26,"y":3},{"v":0,"x":27,"y":3},{"v":0,"x":0,"y":4},{"v":0,"x":1,"y":4},{"v":0,"x":2,"y":4},{"v":0,"x":3,"y":4},{"v":0,"x":4,"y":4},{"v":0,"x":5,"y":4},{"v":0,"x":6,"y":4},{"v":0,"x":7,"y":4},{"v":0,"x":8,"y":4},{"v":0,"x":9,"y":4},{"v":0,"x":10,"y":4},{"v":0,"x":11,"y":4},{"v":0,"x":12,"y":4},{"v":0,"x":13,"y":4},{"v":0,"x":14,"y":4},{"v":0,"x":15,"y":4},{"v":0,"x":16,"y":4},{"v":0,"x":17,"y":4},{"v":0,"x":18,"y":4},{"v":0,"x":19,"y":4},{"v":0,"x":20,"y":4},{"v":0,"x":21,"y":4},{"v":0,"x":22,"y":4},{"v":0,"x":23,"y":4},{"v":0,"x":24,"y":4},{"v":0,"x":25,"y":4},{"v":0,"x":26,"y":4},{"v":0,"x":27,"y":4},{"v":0,"x":0,"y":5},{"v":0,"x":1,"y":5},{"v":0,"x":2,"y":5},{"v":0,"x":3,"y":5},{"v":0,"x":4,"y":5},{"v":0,"x":5,"y":5},{"v":0,"x":6,"y":5},{"v":0,"x":7,"y":5},{"v":0,"x":8,"y":5},{"v":0,"x":9,"y":5},{"v":0,"x":10,"y":5},{"v":0,"x":11,"y":5},{"v":0,"x":12,"y":5},{"v":0,"x":13,"y":5},{"v":0,"x":14,"y":5},{"v":0,"x":15,"y":5},{"v":0,"x":16,"y":5},{"v":0,"x":17,"y":5},{"v":0,"x":18,"y":5},{"v":0,"x":19,"y":5},{"v":67,"x":20,"y":5},{"v":232,"x":21,"y":5},{"v":39,"x":22,"y":5},{"v":0,"x":23,"y":5},{"v":0,"x":24,"y":5},{"v":0,"x":25,"y":5},{"v":0,"x":26,"y":5},{"v":0,"x":27,"y":5},{"v":0,"x":0,"y":6},{"v":0,"x":1,"y":6},{"v":0,"x":2,"y":6},{"v":0,"x":3,"y":6},{"v":62,"x":4,"y":6},{"v":81,"x":5,"y":6},{"v":0,"x":6,"y":6},{"v":0,"x":7,"y":6},{"v":0,"x":8,"y":6},{"v":0,"x":9,"y":6},{"v":0,"x":10,"y":6},{"v":0,"x":11,"y":6},{"v":0,"x":12,"y":6},{"v":0,"x":13,"y":6},{"v":0,"x":14,"y":6},{"v":0,"x":15,"y":6},{"v":0,"x":16,"y":6},{"v":0,"x":17,"y":6},{"v":0,"x":18,"y":6},{"v":0,"x":19,"y":6},{"v":120,"x":20,"y":6},{"v":180,"x":21,"y":6},{"v":39,"x":22,"y":6},{"v":0,"x":23,"y":6},{"v":0,"x":24,"y":6},{"v":0,"x":25,"y":6},{"v":0,"x":26,"y":6},{"v":0,"x":27,"y":6},{"v":0,"x":0,"y":7},{"v":0,"x":1,"y":7},{"v":0,"x":2,"y":7},{"v":0,"x":3,"y":7},{"v":126,"x":4,"y":7},{"v":163,"x":5,"y":7},{"v":0,"x":6,"y":7},{"v":0,"x":7,"y":7},{"v":0,"x":8,"y":7},{"v":0,"x":9,"y":7},{"v":0,"x":10,"y":7},{"v":0,"x":11,"y":7},{"v":0,"x":12,"y":7},{"v":0,"x":13,"y":7},{"v":0,"x":14,"y":7},{"v":0,"x":15,"y":7},{"v":0,"x":16,"y":7},{"v":0,"x":17,"y":7},{"v":0,"x":18,"y":7},{"v":2,"x":19,"y":7},{"v":153,"x":20,"y":7},{"v":210,"x":21,"y":7},{"v":40,"x":22,"y":7},{"v":0,"x":23,"y":7},{"v":0,"x":24,"y":7},{"v":0,"x":25,"y":7},{"v":0,"x":26,"y":7},{"v":0,"x":27,"y":7},{"v":0,"x":0,"y":8},{"v":0,"x":1,"y":8},{"v":0,"x":2,"y":8},{"v":0,"x":3,"y":8},{"v":220,"x":4,"y":8},{"v":163,"x":5,"y":8},{"v":0,"x":6,"y":8},{"v":0,"x":7,"y":8},{"v":0,"x":8,"y":8},{"v":0,"x":9,"y":8},{"v":0,"x":10,"y":8},{"v":0,"x":11,"y":8},{"v":0,"x":12,"y":8},{"v":0,"x":13,"y":8},{"v":0,"x":14,"y":8},{"v":0,"x":15,"y":8},{"v":0,"x":16,"y":8},{"v":0,"x":17,"y":8},{"v":0,"x":18,"y":8},{"v":27,"x":19,"y":8},{"v":254,"x":20,"y":8},{"v":162,"x":21,"y":8},{"v":0,"x":22,"y":8},{"v":0,"x":23,"y":8},{"v":0,"x":24,"y":8},{"v":0,"x":25,"y":8},{"v":0,"x":26,"y":8},{"v":0,"x":27,"y":8},{"v":0,"x":0,"y":9},{"v":0,"x":1,"y":9},{"v":0,"x":2,"y":9},{"v":0,"x":3,"y":9},{"v":222,"x":4,"y":9},{"v":163,"x":5,"y":9},{"v":0,"x":6,"y":9},{"v":0,"x":7,"y":9},{"v":0,"x":8,"y":9},{"v":0,"x":9,"y":9},{"v":0,"x":10,"y":9},{"v":0,"x":11,"y":9},{"v":0,"x":12,"y":9},{"v":0,"x":13,"y":9},{"v":0,"x":14,"y":9},{"v":0,"x":15,"y":9},{"v":0,"x":16,"y":9},{"v":0,"x":17,"y":9},{"v":0,"x":18,"y":9},{"v":183,"x":19,"y":9},{"v":254,"x":20,"y":9},{"v":125,"x":21,"y":9},{"v":0,"x":22,"y":9},{"v":0,"x":23,"y":9},{"v":0,"x":24,"y":9},{"v":0,"x":25,"y":9},{"v":0,"x":26,"y":9},{"v":0,"x":27,"y":9},{"v":0,"x":0,"y":10},{"v":0,"x":1,"y":10},{"v":0,"x":2,"y":10},{"v":46,"x":3,"y":10},{"v":245,"x":4,"y":10},{"v":163,"x":5,"y":10},{"v":0,"x":6,"y":10},{"v":0,"x":7,"y":10},{"v":0,"x":8,"y":10},{"v":0,"x":9,"y":10},{"v":0,"x":10,"y":10},{"v":0,"x":11,"y":10},{"v":0,"x":12,"y":10},{"v":0,"x":13,"y":10},{"v":0,"x":14,"y":10},{"v":0,"x":15,"y":10},{"v":0,"x":16,"y":10},{"v":0,"x":17,"y":10},{"v":0,"x":18,"y":10},{"v":198,"x":19,"y":10},{"v":254,"x":20,"y":10},{"v":56,"x":21,"y":10},{"v":0,"x":22,"y":10},{"v":0,"x":23,"y":10},{"v":0,"x":24,"y":10},{"v":0,"x":25,"y":10},{"v":0,"x":26,"y":10},{"v":0,"x":27,"y":10},{"v":0,"x":0,"y":11},{"v":0,"x":1,"y":11},{"v":0,"x":2,"y":11},{"v":120,"x":3,"y":11},{"v":254,"x":4,"y":11},{"v":163,"x":5,"y":11},{"v":0,"x":6,"y":11},{"v":0,"x":7,"y":11},{"v":0,"x":8,"y":11},{"v":0,"x":9,"y":11},{"v":0,"x":10,"y":11},{"v":0,"x":11,"y":11},{"v":0,"x":12,"y":11},{"v":0,"x":13,"y":11},{"v":0,"x":14,"y":11},{"v":0,"x":15,"y":11},{"v":0,"x":16,"y":11},{"v":0,"x":17,"y":11},{"v":23,"x":18,"y":11},{"v":231,"x":19,"y":11},{"v":254,"x":20,"y":11},{"v":29,"x":21,"y":11},{"v":0,"x":22,"y":11},{"v":0,"x":23,"y":11},{"v":0,"x":24,"y":11},{"v":0,"x":25,"y":11},{"v":0,"x":26,"y":11},{"v":0,"x":27,"y":11},{"v":0,"x":0,"y":12},{"v":0,"x":1,"y":12},{"v":0,"x":2,"y":12},{"v":159,"x":3,"y":12},{"v":254,"x":4,"y":12},{"v":120,"x":5,"y":12},{"v":0,"x":6,"y":12},{"v":0,"x":7,"y":12},{"v":0,"x":8,"y":12},{"v":0,"x":9,"y":12},{"v":0,"x":10,"y":12},{"v":0,"x":11,"y":12},{"v":0,"x":12,"y":12},{"v":0,"x":13,"y":12},{"v":0,"x":14,"y":12},{"v":0,"x":15,"y":12},{"v":0,"x":16,"y":12},{"v":0,"x":17,"y":12},{"v":163,"x":18,"y":12},{"v":254,"x":19,"y":12},{"v":216,"x":20,"y":12},{"v":16,"x":21,"y":12},{"v":0,"x":22,"y":12},{"v":0,"x":23,"y":12},{"v":0,"x":24,"y":12},{"v":0,"x":25,"y":12},{"v":0,"x":26,"y":12},{"v":0,"x":27,"y":12},{"v":0,"x":0,"y":13},{"v":0,"x":1,"y":13},{"v":0,"x":2,"y":13},{"v":159,"x":3,"y":13},{"v":254,"x":4,"y":13},{"v":67,"x":5,"y":13},{"v":0,"x":6,"y":13},{"v":0,"x":7,"y":13},{"v":0,"x":8,"y":13},{"v":0,"x":9,"y":13},{"v":0,"x":10,"y":13},{"v":0,"x":11,"y":13},{"v":0,"x":12,"y":13},{"v":0,"x":13,"y":13},{"v":0,"x":14,"y":13},{"v":14,"x":15,"y":13},{"v":86,"x":16,"y":13},{"v":178,"x":17,"y":13},{"v":248,"x":18,"y":13},{"v":254,"x":19,"y":13},{"v":91,"x":20,"y":13},{"v":0,"x":21,"y":13},{"v":0,"x":22,"y":13},{"v":0,"x":23,"y":13},{"v":0,"x":24,"y":13},{"v":0,"x":25,"y":13},{"v":0,"x":26,"y":13},{"v":0,"x":27,"y":13},{"v":0,"x":0,"y":14},{"v":0,"x":1,"y":14},{"v":0,"x":2,"y":14},{"v":159,"x":3,"y":14},{"v":254,"x":4,"y":14},{"v":85,"x":5,"y":14},{"v":0,"x":6,"y":14},{"v":0,"x":7,"y":14},{"v":0,"x":8,"y":14},{"v":47,"x":9,"y":14},{"v":49,"x":10,"y":14},{"v":116,"x":11,"y":14},{"v":144,"x":12,"y":14},{"v":150,"x":13,"y":14},{"v":241,"x":14,"y":14},{"v":243,"x":15,"y":14},{"v":234,"x":16,"y":14},{"v":179,"x":17,"y":14},{"v":241,"x":18,"y":14},{"v":252,"x":19,"y":14},{"v":40,"x":20,"y":14},{"v":0,"x":21,"y":14},{"v":0,"x":22,"y":14},{"v":0,"x":23,"y":14},{"v":0,"x":24,"y":14},{"v":0,"x":25,"y":14},{"v":0,"x":26,"y":14},{"v":0,"x":27,"y":14},{"v":0,"x":0,"y":15},{"v":0,"x":1,"y":15},{"v":0,"x":2,"y":15},{"v":150,"x":3,"y":15},{"v":253,"x":4,"y":15},{"v":237,"x":5,"y":15},{"v":207,"x":6,"y":15},{"v":207,"x":7,"y":15},{"v":207,"x":8,"y":15},{"v":253,"x":9,"y":15},{"v":254,"x":10,"y":15},{"v":250,"x":11,"y":15},{"v":240,"x":12,"y":15},{"v":198,"x":13,"y":15},{"v":143,"x":14,"y":15},{"v":91,"x":15,"y":15},{"v":28,"x":16,"y":15},{"v":5,"x":17,"y":15},{"v":233,"x":18,"y":15},{"v":250,"x":19,"y":15},{"v":0,"x":20,"y":15},{"v":0,"x":21,"y":15},{"v":0,"x":22,"y":15},{"v":0,"x":23,"y":15},{"v":0,"x":24,"y":15},{"v":0,"x":25,"y":15},{"v":0,"x":26,"y":15},{"v":0,"x":27,"y":15},{"v":0,"x":0,"y":16},{"v":0,"x":1,"y":16},{"v":0,"x":2,"y":16},{"v":0,"x":3,"y":16},{"v":119,"x":4,"y":16},{"v":177,"x":5,"y":16},{"v":177,"x":6,"y":16},{"v":177,"x":7,"y":16},{"v":177,"x":8,"y":16},{"v":177,"x":9,"y":16},{"v":98,"x":10,"y":16},{"v":56,"x":11,"y":16},{"v":0,"x":12,"y":16},{"v":0,"x":13,"y":16},{"v":0,"x":14,"y":16},{"v":0,"x":15,"y":16},{"v":0,"x":16,"y":16},{"v":102,"x":17,"y":16},{"v":254,"x":18,"y":16},{"v":220,"x":19,"y":16},{"v":0,"x":20,"y":16},{"v":0,"x":21,"y":16},{"v":0,"x":22,"y":16},{"v":0,"x":23,"y":16},{"v":0,"x":24,"y":16},{"v":0,"x":25,"y":16},{"v":0,"x":26,"y":16},{"v":0,"x":27,"y":16},{"v":0,"x":0,"y":17},{"v":0,"x":1,"y":17},{"v":0,"x":2,"y":17},{"v":0,"x":3,"y":17},{"v":0,"x":4,"y":17},{"v":0,"x":5,"y":17},{"v":0,"x":6,"y":17},{"v":0,"x":7,"y":17},{"v":0,"x":8,"y":17},{"v":0,"x":9,"y":17},{"v":0,"x":10,"y":17},{"v":0,"x":11,"y":17},{"v":0,"x":12,"y":17},{"v":0,"x":13,"y":17},{"v":0,"x":14,"y":17},{"v":0,"x":15,"y":17},{"v":0,"x":16,"y":17},{"v":169,"x":17,"y":17},{"v":254,"x":18,"y":17},{"v":137,"x":19,"y":17},{"v":0,"x":20,"y":17},{"v":0,"x":21,"y":17},{"v":0,"x":22,"y":17},{"v":0,"x":23,"y":17},{"v":0,"x":24,"y":17},{"v":0,"x":25,"y":17},{"v":0,"x":26,"y":17},{"v":0,"x":27,"y":17},{"v":0,"x":0,"y":18},{"v":0,"x":1,"y":18},{"v":0,"x":2,"y":18},{"v":0,"x":3,"y":18},{"v":0,"x":4,"y":18},{"v":0,"x":5,"y":18},{"v":0,"x":6,"y":18},{"v":0,"x":7,"y":18},{"v":0,"x":8,"y":18},{"v":0,"x":9,"y":18},{"v":0,"x":10,"y":18},{"v":0,"x":11,"y":18},{"v":0,"x":12,"y":18},{"v":0,"x":13,"y":18},{"v":0,"x":14,"y":18},{"v":0,"x":15,"y":18},{"v":0,"x":16,"y":18},{"v":169,"x":17,"y":18},{"v":254,"x":18,"y":18},{"v":57,"x":19,"y":18},{"v":0,"x":20,"y":18},{"v":0,"x":21,"y":18},{"v":0,"x":22,"y":18},{"v":0,"x":23,"y":18},{"v":0,"x":24,"y":18},{"v":0,"x":25,"y":18},{"v":0,"x":26,"y":18},{"v":0,"x":27,"y":18},{"v":0,"x":0,"y":19},{"v":0,"x":1,"y":19},{"v":0,"x":2,"y":19},{"v":0,"x":3,"y":19},{"v":0,"x":4,"y":19},{"v":0,"x":5,"y":19},{"v":0,"x":6,"y":19},{"v":0,"x":7,"y":19},{"v":0,"x":8,"y":19},{"v":0,"x":9,"y":19},{"v":0,"x":10,"y":19},{"v":0,"x":11,"y":19},{"v":0,"x":12,"y":19},{"v":0,"x":13,"y":19},{"v":0,"x":14,"y":19},{"v":0,"x":15,"y":19},{"v":0,"x":16,"y":19},{"v":169,"x":17,"y":19},{"v":254,"x":18,"y":19},{"v":57,"x":19,"y":19},{"v":0,"x":20,"y":19},{"v":0,"x":21,"y":19},{"v":0,"x":22,"y":19},{"v":0,"x":23,"y":19},{"v":0,"x":24,"y":19},{"v":0,"x":25,"y":19},{"v":0,"x":26,"y":19},{"v":0,"x":27,"y":19},{"v":0,"x":0,"y":20},{"v":0,"x":1,"y":20},{"v":0,"x":2,"y":20},{"v":0,"x":3,"y":20},{"v":0,"x":4,"y":20},{"v":0,"x":5,"y":20},{"v":0,"x":6,"y":20},{"v":0,"x":7,"y":20},{"v":0,"x":8,"y":20},{"v":0,"x":9,"y":20},{"v":0,"x":10,"y":20},{"v":0,"x":11,"y":20},{"v":0,"x":12,"y":20},{"v":0,"x":13,"y":20},{"v":0,"x":14,"y":20},{"v":0,"x":15,"y":20},{"v":0,"x":16,"y":20},{"v":169,"x":17,"y":20},{"v":255,"x":18,"y":20},{"v":94,"x":19,"y":20},{"v":0,"x":20,"y":20},{"v":0,"x":21,"y":20},{"v":0,"x":22,"y":20},{"v":0,"x":23,"y":20},{"v":0,"x":24,"y":20},{"v":0,"x":25,"y":20},{"v":0,"x":26,"y":20},{"v":0,"x":27,"y":20},{"v":0,"x":0,"y":21},{"v":0,"x":1,"y":21},{"v":0,"x":2,"y":21},{"v":0,"x":3,"y":21},{"v":0,"x":4,"y":21},{"v":0,"x":5,"y":21},{"v":0,"x":6,"y":21},{"v":0,"x":7,"y":21},{"v":0,"x":8,"y":21},{"v":0,"x":9,"y":21},{"v":0,"x":10,"y":21},{"v":0,"x":11,"y":21},{"v":0,"x":12,"y":21},{"v":0,"x":13,"y":21},{"v":0,"x":14,"y":21},{"v":0,"x":15,"y":21},{"v":0,"x":16,"y":21},{"v":169,"x":17,"y":21},{"v":254,"x":18,"y":21},{"v":96,"x":19,"y":21},{"v":0,"x":20,"y":21},{"v":0,"x":21,"y":21},{"v":0,"x":22,"y":21},{"v":0,"x":23,"y":21},{"v":0,"x":24,"y":21},{"v":0,"x":25,"y":21},{"v":0,"x":26,"y":21},{"v":0,"x":27,"y":21},{"v":0,"x":0,"y":22},{"v":0,"x":1,"y":22},{"v":0,"x":2,"y":22},{"v":0,"x":3,"y":22},{"v":0,"x":4,"y":22},{"v":0,"x":5,"y":22},{"v":0,"x":6,"y":22},{"v":0,"x":7,"y":22},{"v":0,"x":8,"y":22},{"v":0,"x":9,"y":22},{"v":0,"x":10,"y":22},{"v":0,"x":11,"y":22},{"v":0,"x":12,"y":22},{"v":0,"x":13,"y":22},{"v":0,"x":14,"y":22},{"v":0,"x":15,"y":22},{"v":0,"x":16,"y":22},{"v":169,"x":17,"y":22},{"v":254,"x":18,"y":22},{"v":153,"x":19,"y":22},{"v":0,"x":20,"y":22},{"v":0,"x":21,"y":22},{"v":0,"x":22,"y":22},{"v":0,"x":23,"y":22},{"v":0,"x":24,"y":22},{"v":0,"x":25,"y":22},{"v":0,"x":26,"y":22},{"v":0,"x":27,"y":22},{"v":0,"x":0,"y":23},{"v":0,"x":1,"y":23},{"v":0,"x":2,"y":23},{"v":0,"x":3,"y":23},{"v":0,"x":4,"y":23},{"v":0,"x":5,"y":23},{"v":0,"x":6,"y":23},{"v":0,"x":7,"y":23},{"v":0,"x":8,"y":23},{"v":0,"x":9,"y":23},{"v":0,"x":10,"y":23},{"v":0,"x":11,"y":23},{"v":0,"x":12,"y":23},{"v":0,"x":13,"y":23},{"v":0,"x":14,"y":23},{"v":0,"x":15,"y":23},{"v":0,"x":16,"y":23},{"v":169,"x":17,"y":23},{"v":255,"x":18,"y":23},{"v":153,"x":19,"y":23},{"v":0,"x":20,"y":23},{"v":0,"x":21,"y":23},{"v":0,"x":22,"y":23},{"v":0,"x":23,"y":23},{"v":0,"x":24,"y":23},{"v":0,"x":25,"y":23},{"v":0,"x":26,"y":23},{"v":0,"x":27,"y":23},{"v":0,"x":0,"y":24},{"v":0,"x":1,"y":24},{"v":0,"x":2,"y":24},{"v":0,"x":3,"y":24},{"v":0,"x":4,"y":24},{"v":0,"x":5,"y":24},{"v":0,"x":6,"y":24},{"v":0,"x":7,"y":24},{"v":0,"x":8,"y":24},{"v":0,"x":9,"y":24},{"v":0,"x":10,"y":24},{"v":0,"x":11,"y":24},{"v":0,"x":12,"y":24},{"v":0,"x":13,"y":24},{"v":0,"x":14,"y":24},{"v":0,"x":15,"y":24},{"v":0,"x":16,"y":24},{"v":96,"x":17,"y":24},{"v":254,"x":18,"y":24},{"v":153,"x":19,"y":24},{"v":0,"x":20,"y":24},{"v":0,"x":21,"y":24},{"v":0,"x":22,"y":24},{"v":0,"x":23,"y":24},{"v":0,"x":24,"y":24},{"v":0,"x":25,"y":24},{"v":0,"x":26,"y":24},{"v":0,"x":27,"y":24},{"v":0,"x":0,"y":25},{"v":0,"x":1,"y":25},{"v":0,"x":2,"y":25},{"v":0,"x":3,"y":25},{"v":0,"x":4,"y":25},{"v":0,"x":5,"y":25},{"v":0,"x":6,"y":25},{"v":0,"x":7,"y":25},{"v":0,"x":8,"y":25},{"v":0,"x":9,"y":25},{"v":0,"x":10,"y":25},{"v":0,"x":11,"y":25},{"v":0,"x":12,"y":25},{"v":0,"x":13,"y":25},{"v":0,"x":14,"y":25},{"v":0,"x":15,"y":25},{"v":0,"x":16,"y":25},{"v":0,"x":17,"y":25},{"v":0,"x":18,"y":25},{"v":0,"x":19,"y":25},{"v":0,"x":20,"y":25},{"v":0,"x":21,"y":25},{"v":0,"x":22,"y":25},{"v":0,"x":23,"y":25},{"v":0,"x":24,"y":25},{"v":0,"x":25,"y":25},{"v":0,"x":26,"y":25},{"v":0,"x":27,"y":25},{"v":0,"x":0,"y":26},{"v":0,"x":1,"y":26},{"v":0,"x":2,"y":26},{"v":0,"x":3,"y":26},{"v":0,"x":4,"y":26},{"v":0,"x":5,"y":26},{"v":0,"x":6,"y":26},{"v":0,"x":7,"y":26},{"v":0,"x":8,"y":26},{"v":0,"x":9,"y":26},{"v":0,"x":10,"y":26},{"v":0,"x":11,"y":26},{"v":0,"x":12,"y":26},{"v":0,"x":13,"y":26},{"v":0,"x":14,"y":26},{"v":0,"x":15,"y":26},{"v":0,"x":16,"y":26},{"v":0,"x":17,"y":26},{"v":0,"x":18,"y":26},{"v":0,"x":19,"y":26},{"v":0,"x":20,"y":26},{"v":0,"x":21,"y":26},{"v":0,"x":22,"y":26},{"v":0,"x":23,"y":26},{"v":0,"x":24,"y":26},{"v":0,"x":25,"y":26},{"v":0,"x":26,"y":26},{"v":0,"x":27,"y":26},{"v":0,"x":0,"y":27},{"v":0,"x":1,"y":27},{"v":0,"x":2,"y":27},{"v":0,"x":3,"y":27},{"v":0,"x":4,"y":27},{"v":0,"x":5,"y":27},{"v":0,"x":6,"y":27},{"v":0,"x":7,"y":27},{"v":0,"x":8,"y":27},{"v":0,"x":9,"y":27},{"v":0,"x":10,"y":27},{"v":0,"x":11,"y":27},{"v":0,"x":12,"y":27},{"v":0,"x":13,"y":27},{"v":0,"x":14,"y":27},{"v":0,"x":15,"y":27},{"v":0,"x":16,"y":27},{"v":0,"x":17,"y":27},{"v":0,"x":18,"y":27},{"v":0,"x":19,"y":27},{"v":0,"x":20,"y":27},{"v":0,"x":21,"y":27},{"v":0,"x":22,"y":27},{"v":0,"x":23,"y":27},{"v":0,"x":24,"y":27},{"v":0,"x":25,"y":27},{"v":0,"x":26,"y":27},{"v":0,"x":27,"y":27}]},"encoding":{"color":{"field":"v","legend":null,"scale":{"reverse":true,"scheme":"greys"},"type":"quantitative"},"x":{"axis":null,"field":"x","type":"ordinal"},"y":{"axis":null,"field":"y","type":"ordinal"}},"height":60,"mark":"rect","width":60},{"data":{"values":[{"v":0,"x":0,"y":0},{"v":0,"x":1,"y":0},{"v":0,"x":2,"y":0},{"v":0,"x":3,"y":0},{"v":0,"x":4,"y":0},{"v":0,"x":5,"y":0},{"v":0,"x":6,"y":0},{"v":0,"x":7,"y":0},{"v":0,"x":8,"y":0},{"v":0,"x":9,"y":0},{"v":0,"x":10,"y":0},{"v":0,"x":11,"y":0},{"v":0,"x":12,"y":0},{"v":0,"x":13,"y":0},{"v":0,"x":14,"y":0},{"v":0,"x":15,"y":0},{"v":0,"x":16,"y":0},{"v":0,"x":17,"y":0},{"v":0,"x":18,"y":0},{"v":0,"x":19,"y":0},{"v":0,"x":20,"y":0},{"v":0,"x":21,"y":0},{"v":0,"x":22,"y":0},{"v":0,"x":23,"y":0},{"v":0,"x":24,"y":0},{"v":0,"x":25,"y":0},{"v":0,"x":26,"y":0},{"v":0,"x":27,"y":0},{"v":0,"x":0,"y":1},{"v":0,"x":1,"y":1},{"v":0,"x":2,"y":1},{"v":0,"x":3,"y":1},{"v":0,"x":4,"y":1},{"v":0,"x":5,"y":1},{"v":0,"x":6,"y":1},{"v":0,"x":7,"y":1},{"v":0,"x":8,"y":1},{"v":0,"x":9,"y":1},{"v":0,"x":10,"y":1},{"v":0,"x":11,"y":1},{"v":0,"x":12,"y":1},{"v":0,"x":13,"y":1},{"v":0,"x":14,"y":1},{"v":0,"x":15,"y":1},{"v":0,"x":16,"y":1},{"v":0,"x":17,"y":1},{"v":0,"x":18,"y":1},{"v":0,"x":19,"y":1},{"v":0,"x":20,"y":1},{"v":0,"x":21,"y":1},{"v":0,"x":22,"y":1},{"v":0,"x":23,"y":1},{"v":0,"x":24,"y":1},{"v":0,"x":25,"y":1},{"v":0,"x":26,"y":1},{"v":0,"x":27,"y":1},{"v":0,"x":0,"y":2},{"v":0,"x":1,"y":2},{"v":0,"x":2,"y":2},{"v":0,"x":3,"y":2},{"v":0,"x":4,"y":2},{"v":0,"x":5,"y":2},{"v":0,"x":6,"y":2},{"v":0,"x":7,"y":2},{"v":0,"x":8,"y":2},{"v":0,"x":9,"y":2},{"v":0,"x":10,"y":2},{"v":0,"x":11,"y":2},{"v":0,"x":12,"y":2},{"v":0,"x":13,"y":2},{"v":0,"x":14,"y":2},{"v":0,"x":15,"y":2},{"v":0,"x":16,"y":2},{"v":0,"x":17,"y":2},{"v":0,"x":18,"y":2},{"v":0,"x":19,"y":2},{"v":0,"x":20,"y":2},{"v":0,"x":21,"y":2},{"v":0,"x":22,"y":2},{"v":0,"x":23,"y":2},{"v":0,"x":24,"y":2},{"v":0,"x":25,"y":2},{"v":0,"x":26,"y":2},{"v":0,"x":27,"y":2},{"v":0,"x":0,"y":3},{"v":0,"x":1,"y":3},{"v":0,"x":2,"y":3},{"v":0,"x":3,"y":3},{"v":0,"x":4,"y":3},{"v":0,"x":5,"y":3},{"v":0,"x":6,"y":3},{"v":0,"x":7,"y":3},{"v":0,"x":8,"y":3},{"v":0,"x":9,"y":3},{"v":0,"x":10,"y":3},{"v":0,"x":11,"y":3},{"v":0,"x":12,"y":3},{"v":0,"x":13,"y":3},{"v":0,"x":14,"y":3},{"v":0,"x":15,"y":3},{"v":0,"x":16,"y":3},{"v":0,"x":17,"y":3},{"v":0,"x":18,"y":3},{"v":0,"x":19,"y":3},{"v":0,"x":20,"y":3},{"v":0,"x":21,"y":3},{"v":0,"x":22,"y":3},{"v":0,"x":23,"y":3},{"v":0,"x":24,"y":3},{"v":0,"x":25,"y":3},{"v":0,"x":26,"y":3},{"v":0,"x":27,"y":3},{"v":0,"x":0,"y":4},{"v":0,"x":1,"y":4},{"v":0,"x":2,"y":4},{"v":0,"x":3,"y":4},{"v":0,"x":4,"y":4},{"v":0,"x":5,"y":4},{"v":0,"x":6,"y":4},{"v":0,"x":7,"y":4},{"v":0,"x":8,"y":4},{"v":0,"x":9,"y":4},{"v":0,"x":10,"y":4},{"v":0,"x":11,"y":4},{"v":0,"x":12,"y":4},{"v":0,"x":13,"y":4},{"v":0,"x":14,"y":4},{"v":0,"x":15,"y":4},{"v":0,"x":16,"y":4},{"v":0,"x":17,"y":4},{"v":0,"x":18,"y":4},{"v":0,"x":19,"y":4},{"v":0,"x":20,"y":4},{"v":0,"x":21,"y":4},{"v":0,"x":22,"y":4},{"v":0,"x":23,"y":4},{"v":0,"x":24,"y":4},{"v":0,"x":25,"y":4},{"v":0,"x":26,"y":4},{"v":0,"x":27,"y":4},{"v":0,"x":0,"y":5},{"v":0,"x":1,"y":5},{"v":0,"x":2,"y":5},{"v":0,"x":3,"y":5},{"v":0,"x":4,"y":5},{"v":0,"x":5,"y":5},{"v":0,"x":6,"y":5},{"v":0,"x":7,"y":5},{"v":0,"x":8,"y":5},{"v":0,"x":9,"y":5},{"v":0,"x":10,"y":5},{"v":0,"x":11,"y":5},{"v":0,"x":12,"y":5},{"v":0,"x":13,"y":5},{"v":0,"x":14,"y":5},{"v":0,"x":15,"y":5},{"v":0,"x":16,"y":5},{"v":0,"x":17,"y":5},{"v":124,"x":18,"y":5},{"v":253,"x":19,"y":5},{"v":255,"x":20,"y":5},{"v":63,"x":21,"y":5},{"v":0,"x":22,"y":5},{"v":0,"x":23,"y":5},{"v":0,"x":24,"y":5},{"v":0,"x":25,"y":5},{"v":0,"x":26,"y":5},{"v":0,"x":27,"y":5},{"v":0,"x":0,"y":6},{"v":0,"x":1,"y":6},{"v":0,"x":2,"y":6},{"v":0,"x":3,"y":6},{"v":0,"x":4,"y":6},{"v":0,"x":5,"y":6},{"v":0,"x":6,"y":6},{"v":0,"x":7,"y":6},{"v":0,"x":8,"y":6},{"v":0,"x":9,"y":6},{"v":0,"x":10,"y":6},{"v":0,"x":11,"y":6},{"v":0,"x":12,"y":6},{"v":0,"x":13,"y":6},{"v":0,"x":14,"y":6},{"v":0,"x":15,"y":6},{"v":0,"x":16,"y":6},{"v":96,"x":17,"y":6},{"v":244,"x":18,"y":6},{"v":251,"x":19,"y":6},{"v":253,"x":20,"y":6},{"v":62,"x":21,"y":6},{"v":0,"x":22,"y":6},{"v":0,"x":23,"y":6},{"v":0,"x":24,"y":6},{"v":0,"x":25,"y":6},{"v":0,"x":26,"y":6},{"v":0,"x":27,"y":6},{"v":0,"x":0,"y":7},{"v":0,"x":1,"y":7},{"v":0,"x":2,"y":7},{"v":0,"x":3,"y":7},{"v":0,"x":4,"y":7},{"v":0,"x":5,"y":7},{"v":0,"x":6,"y":7},{"v":0,"x":7,"y":7},{"v":0,"x":8,"y":7},{"v":0,"x":9,"y":7},{"v":0,"x":10,"y":7},{"v":0,"x":11,"y":7},{"v":0,"x":12,"y":7},{"v":0,"x":13,"y":7},{"v":0,"x":14,"y":7},{"v":0,"x":15,"y":7},{"v":0,"x":16,"y":7},{"v":127,"x":17,"y":7},{"v":251,"x":18,"y":7},{"v":251,"x":19,"y":7},{"v":253,"x":20,"y":7},{"v":62,"x":21,"y":7},{"v":0,"x":22,"y":7},{"v":0,"x":23,"y":7},{"v":0,"x":24,"y":7},{"v":0,"x":25,"y":7},{"v":0,"x":26,"y":7},{"v":0,"x":27,"y":7},{"v":0,"x":0,"y":8},{"v":0,"x":1,"y":8},{"v":0,"x":2,"y":8},{"v":0,"x":3,"y":8},{"v":0,"x":4,"y":8},{"v":0,"x":5,"y":8},{"v":0,"x":6,"y":8},{"v":0,"x":7,"y":8},{"v":0,"x":8,"y":8},{"v":0,"x":9,"y":8},{"v":0,"x":10,"y":8},{"v":0,"x":11,"y":8},{"v":0,"x":12,"y":8},{"v":0,"x":13,"y":8},{"v":0,"x":14,"y":8},{"v":0,"x":15,"y":8},{"v":68,"x":16,"y":8},{"v":236,"x":17,"y":8},{"v":251,"x":18,"y":8},{"v":211,"x":19,"y":8},{"v":31,"x":20,"y":8},{"v":8,"x":21,"y":8},{"v":0,"x":22,"y":8},{"v":0,"x":23,"y":8},{"v":0,"x":24,"y":8},{"v":0,"x":25,"y":8},{"v":0,"x":26,"y":8},{"v":0,"x":27,"y":8},{"v":0,"x":0,"y":9},{"v":0,"x":1,"y":9},{"v":0,"x":2,"y":9},{"v":0,"x":3,"y":9},{"v":0,"x":4,"y":9},{"v":0,"x":5,"y":9},{"v":0,"x":6,"y":9},{"v":0,"x":7,"y":9},{"v":0,"x":8,"y":9},{"v":0,"x":9,"y":9},{"v":0,"x":10,"y":9},{"v":0,"x":11,"y":9},{"v":0,"x":12,"y":9},{"v":0,"x":13,"y":9},{"v":0,"x":14,"y":9},{"v":60,"x":15,"y":9},{"v":228,"x":16,"y":9},{"v":251,"x":17,"y":9},{"v":251,"x":18,"y":9},{"v":94,"x":19,"y":9},{"v":0,"x":20,"y":9},{"v":0,"x":21,"y":9},{"v":0,"x":22,"y":9},{"v":0,"x":23,"y":9},{"v":0,"x":24,"y":9},{"v":0,"x":25,"y":9},{"v":0,"x":26,"y":9},{"v":0,"x":27,"y":9},{"v":0,"x":0,"y":10},{"v":0,"x":1,"y":10},{"v":0,"x":2,"y":10},{"v":0,"x":3,"y":10},{"v":0,"x":4,"y":10},{"v":0,"x":5,"y":10},{"v":0,"x":6,"y":10},{"v":0,"x":7,"y":10},{"v":0,"x":8,"y":10},{"v":0,"x":9,"y":10},{"v":0,"x":10,"y":10},{"v":0,"x":11,"y":10},{"v":0,"x":12,"y":10},{"v":0,"x":13,"y":10},{"v":0,"x":14,"y":10},{"v":155,"x":15,"y":10},{"v":253,"x":16,"y":10},{"v":253,"x":17,"y":10},{"v":189,"x":18,"y":10},{"v":0,"x":19,"y":10},{"v":0,"x":20,"y":10},{"v":0,"x":21,"y":10},{"v":0,"x":22,"y":10},{"v":0,"x":23,"y":10},{"v":0,"x":24,"y":10},{"v":0,"x":25,"y":10},{"v":0,"x":26,"y":10},{"v":0,"x":27,"y":10},{"v":0,"x":0,"y":11},{"v":0,"x":1,"y":11},{"v":0,"x":2,"y":11},{"v":0,"x":3,"y":11},{"v":0,"x":4,"y":11},{"v":0,"x":5,"y":11},{"v":0,"x":6,"y":11},{"v":0,"x":7,"y":11},{"v":0,"x":8,"y":11},{"v":0,"x":9,"y":11},{"v":0,"x":10,"y":11},{"v":0,"x":11,"y":11},{"v":0,"x":12,"y":11},{"v":0,"x":13,"y":11},{"v":20,"x":14,"y":11},{"v":253,"x":15,"y":11},{"v":251,"x":16,"y":11},{"v":235,"x":17,"y":11},{"v":66,"x":18,"y":11},{"v":0,"x":19,"y":11},{"v":0,"x":20,"y":11},{"v":0,"x":21,"y":11},{"v":0,"x":22,"y":11},{"v":0,"x":23,"y":11},{"v":0,"x":24,"y":11},{"v":0,"x":25,"y":11},{"v":0,"x":26,"y":11},{"v":0,"x":27,"y":11},{"v":0,"x":0,"y":12},{"v":0,"x":1,"y":12},{"v":0,"x":2,"y":12},{"v":0,"x":3,"y":12},{"v":0,"x":4,"y":12},{"v":0,"x":5,"y":12},{"v":0,"x":6,"y":12},{"v":0,"x":7,"y":12},{"v":0,"x":8,"y":12},{"v":0,"x":9,"y":12},{"v":0,"x":10,"y":12},{"v":0,"x":11,"y":12},{"v":0,"x":12,"y":12},{"v":32,"x":13,"y":12},{"v":205,"x":14,"y":12},{"v":253,"x":15,"y":12},{"v":251,"x":16,"y":12},{"v":126,"x":17,"y":12},{"v":0,"x":18,"y":12},{"v":0,"x":19,"y":12},{"v":0,"x":20,"y":12},{"v":0,"x":21,"y":12},{"v":0,"x":22,"y":12},{"v":0,"x":23,"y":12},{"v":0,"x":24,"y":12},{"v":0,"x":25,"y":12},{"v":0,"x":26,"y":12},{"v":0,"x":27,"y":12},{"v":0,"x":0,"y":13},{"v":0,"x":1,"y":13},{"v":0,"x":2,"y":13},{"v":0,"x":3,"y":13},{"v":0,"x":4,"y":13},{"v":0,"x":5,"y":13},{"v":0,"x":6,"y":13},{"v":0,"x":7,"y":13},{"v":0,"x":8,"y":13},{"v":0,"x":9,"y":13},{"v":0,"x":10,"y":13},{"v":0,"x":11,"y":13},{"v":0,"x":12,"y":13},{"v":104,"x":13,"y":13},{"v":251,"x":14,"y":13},{"v":253,"x":15,"y":13},{"v":184,"x":16,"y":13},{"v":15,"x":17,"y":13},{"v":0,"x":18,"y":13},{"v":0,"x":19,"y":13},{"v":0,"x":20,"y":13},{"v":0,"x":21,"y":13},{"v":0,"x":22,"y":13},{"v":0,"x":23,"y":13},{"v":0,"x":24,"y":13},{"v":0,"x":25,"y":13},{"v":0,"x":26,"y":13},{"v":0,"x":27,"y":13},{"v":0,"x":0,"y":14},{"v":0,"x":1,"y":14},{"v":0,"x":2,"y":14},{"v":0,"x":3,"y":14},{"v":0,"x":4,"y":14},{"v":0,"x":5,"y":14},{"v":0,"x":6,"y":14},{"v":0,"x":7,"y":14},{"v":0,"x":8,"y":14},{"v":0,"x":9,"y":14},{"v":0,"x":10,"y":14},{"v":0,"x":11,"y":14},{"v":80,"x":12,"y":14},{"v":240,"x":13,"y":14},{"v":251,"x":14,"y":14},{"v":193,"x":15,"y":14},{"v":23,"x":16,"y":14},{"v":0,"x":17,"y":14},{"v":0,"x":18,"y":14},{"v":0,"x":19,"y":14},{"v":0,"x":20,"y":14},{"v":0,"x":21,"y":14},{"v":0,"x":22,"y":14},{"v":0,"x":23,"y":14},{"v":0,"x":24,"y":14},{"v":0,"x":25,"y":14},{"v":0,"x":26,"y":14},{"v":0,"x":27,"y":14},{"v":0,"x":0,"y":15},{"v":0,"x":1,"y":15},{"v":0,"x":2,"y":15},{"v":0,"x":3,"y":15},{"v":0,"x":4,"y":15},{"v":0,"x":5,"y":15},{"v":0,"x":6,"y":15},{"v":0,"x":7,"y":15},{"v":0,"x":8,"y":15},{"v":0,"x":9,"y":15},{"v":0,"x":10,"y":15},{"v":32,"x":11,"y":15},{"v":253,"x":12,"y":15},{"v":253,"x":13,"y":15},{"v":253,"x":14,"y":15},{"v":159,"x":15,"y":15},{"v":0,"x":16,"y":15},{"v":0,"x":17,"y":15},{"v":0,"x":18,"y":15},{"v":0,"x":19,"y":15},{"v":0,"x":20,"y":15},{"v":0,"x":21,"y":15},{"v":0,"x":22,"y":15},{"v":0,"x":23,"y":15},{"v":0,"x":24,"y":15},{"v":0,"x":25,"y":15},{"v":0,"x":26,"y":15},{"v":0,"x":27,"y":15},{"v":0,"x":0,"y":16},{"v":0,"x":1,"y":16},{"v":0,"x":2,"y":16},{"v":0,"x":3,"y":16},{"v":0,"x":4,"y":16},{"v":0,"x":5,"y":16},{"v":0,"x":6,"y":16},{"v":0,"x":7,"y":16},{"v":0,"x":8,"y":16},{"v":0,"x":9,"y":16},{"v":0,"x":10,"y":16},{"v":151,"x":11,"y":16},{"v":251,"x":12,"y":16},{"v":251,"x":13,"y":16},{"v":251,"x":14,"y":16},{"v":39,"x":15,"y":16},{"v":0,"x":16,"y":16},{"v":0,"x":17,"y":16},{"v":0,"x":18,"y":16},{"v":0,"x":19,"y":16},{"v":0,"x":20,"y":16},{"v":0,"x":21,"y":16},{"v":0,"x":22,"y":16},{"v":0,"x":23,"y":16},{"v":0,"x":24,"y":16},{"v":0,"x":25,"y":16},{"v":0,"x":26,"y":16},{"v":0,"x":27,"y":16},{"v":0,"x":0,"y":17},{"v":0,"x":1,"y":17},{"v":0,"x":2,"y":17},{"v":0,"x":3,"y":17},{"v":0,"x":4,"y":17},{"v":0,"x":5,"y":17},{"v":0,"x":6,"y":17},{"v":0,"x":7,"y":17},{"v":0,"x":8,"y":17},{"v":0,"x":9,"y":17},{"v":48,"x":10,"y":17},{"v":221,"x":11,"y":17},{"v":251,"x":12,"y":17},{"v":251,"x":13,"y":17},{"v":172,"x":14,"y":17},{"v":0,"x":15,"y":17},{"v":0,"x":16,"y":17},{"v":0,"x":17,"y":17},{"v":0,"x":18,"y":17},{"v":0,"x":19,"y":17},{"v":0,"x":20,"y":17},{"v":0,"x":21,"y":17},{"v":0,"x":22,"y":17},{"v":0,"x":23,"y":17},{"v":0,"x":24,"y":17},{"v":0,"x":25,"y":17},{"v":0,"x":26,"y":17},{"v":0,"x":27,"y":17},{"v":0,"x":0,"y":18},{"v":0,"x":1,"y":18},{"v":0,"x":2,"y":18},{"v":0,"x":3,"y":18},{"v":0,"x":4,"y":18},{"v":0,"x":5,"y":18},{"v":0,"x":6,"y":18},{"v":0,"x":7,"y":18},{"v":0,"x":8,"y":18},{"v":0,"x":9,"y":18},{"v":234,"x":10,"y":18},{"v":251,"x":11,"y":18},{"v":251,"x":12,"y":18},{"v":196,"x":13,"y":18},{"v":12,"x":14,"y":18},{"v":0,"x":15,"y":18},{"v":0,"x":16,"y":18},{"v":0,"x":17,"y":18},{"v":0,"x":18,"y":18},{"v":0,"x":19,"y":18},{"v":0,"x":20,"y":18},{"v":0,"x":21,"y":18},{"v":0,"x":22,"y":18},{"v":0,"x":23,"y":18},{"v":0,"x":24,"y":18},{"v":0,"x":25,"y":18},{"v":0,"x":26,"y":18},{"v":0,"x":27,"y":18},{"v":0,"x":0,"y":19},{"v":0,"x":1,"y":19},{"v":0,"x":2,"y":19},{"v":0,"x":3,"y":19},{"v":0,"x":4,"y":19},{"v":0,"x":5,"y":19},{"v":0,"x":6,"y":19},{"v":0,"x":7,"y":19},{"v":0,"x":8,"y":19},{"v":0,"x":9,"y":19},{"v":253,"x":10,"y":19},{"v":251,"x":11,"y":19},{"v":251,"x":12,"y":19},{"v":89,"x":13,"y":19},{"v":0,"x":14,"y":19},{"v":0,"x":15,"y":19},{"v":0,"x":16,"y":19},{"v":0,"x":17,"y":19},{"v":0,"x":18,"y":19},{"v":0,"x":19,"y":19},{"v":0,"x":20,"y":19},{"v":0,"x":21,"y":19},{"v":0,"x":22,"y":19},{"v":0,"x":23,"y":19},{"v":0,"x":24,"y":19},{"v":0,"x":25,"y":19},{"v":0,"x":26,"y":19},{"v":0,"x":27,"y":19},{"v":0,"x":0,"y":20},{"v":0,"x":1,"y":20},{"v":0,"x":2,"y":20},{"v":0,"x":3,"y":20},{"v":0,"x":4,"y":20},{"v":0,"x":5,"y":20},{"v":0,"x":6,"y":20},{"v":0,"x":7,"y":20},{"v":0,"x":8,"y":20},{"v":159,"x":9,"y":20},{"v":255,"x":10,"y":20},{"v":253,"x":11,"y":20},{"v":253,"x":12,"y":20},{"v":31,"x":13,"y":20},{"v":0,"x":14,"y":20},{"v":0,"x":15,"y":20},{"v":0,"x":16,"y":20},{"v":0,"x":17,"y":20},{"v":0,"x":18,"y":20},{"v":0,"x":19,"y":20},{"v":0,"x":20,"y":20},{"v":0,"x":21,"y":20},{"v":0,"x":22,"y":20},{"v":0,"x":23,"y":20},{"v":0,"x":24,"y":20},{"v":0,"x":25,"y":20},{"v":0,"x":26,"y":20},{"v":0,"x":27,"y":20},{"v":0,"x":0,"y":21},{"v":0,"x":1,"y":21},{"v":0,"x":2,"y":21},{"v":0,"x":3,"y":21},{"v":0,"x":4,"y":21},{"v":0,"x":5,"y":21},{"v":0,"x":6,"y":21},{"v":0,"x":7,"y":21},{"v":48,"x":8,"y":21},{"v":228,"x":9,"y":21},{"v":253,"x":10,"y":21},{"v":247,"x":11,"y":21},{"v":140,"x":12,"y":21},{"v":8,"x":13,"y":21},{"v":0,"x":14,"y":21},{"v":0,"x":15,"y":21},{"v":0,"x":16,"y":21},{"v":0,"x":17,"y":21},{"v":0,"x":18,"y":21},{"v":0,"x":19,"y":21},{"v":0,"x":20,"y":21},{"v":0,"x":21,"y":21},{"v":0,"x":22,"y":21},{"v":0,"x":23,"y":21},{"v":0,"x":24,"y":21},{"v":0,"x":25,"y":21},{"v":0,"x":26,"y":21},{"v":0,"x":27,"y":21},{"v":0,"x":0,"y":22},{"v":0,"x":1,"y":22},{"v":0,"x":2,"y":22},{"v":0,"x":3,"y":22},{"v":0,"x":4,"y":22},{"v":0,"x":5,"y":22},{"v":0,"x":6,"y":22},{"v":0,"x":7,"y":22},{"v":64,"x":8,"y":22},{"v":251,"x":9,"y":22},{"v":253,"x":10,"y":22},{"v":220,"x":11,"y":22},{"v":0,"x":12,"y":22},{"v":0,"x":13,"y":22},{"v":0,"x":14,"y":22},{"v":0,"x":15,"y":22},{"v":0,"x":16,"y":22},{"v":0,"x":17,"y":22},{"v":0,"x":18,"y":22},{"v":0,"x":19,"y":22},{"v":0,"x":20,"y":22},{"v":0,"x":21,"y":22},{"v":0,"x":22,"y":22},{"v":0,"x":23,"y":22},{"v":0,"x":24,"y":22},{"v":0,"x":25,"y":22},{"v":0,"x":26,"y":22},{"v":0,"x":27,"y":22},{"v":0,"x":0,"y":23},{"v":0,"x":1,"y":23},{"v":0,"x":2,"y":23},{"v":0,"x":3,"y":23},{"v":0,"x":4,"y":23},{"v":0,"x":5,"y":23},{"v":0,"x":6,"y":23},{"v":0,"x":7,"y":23},{"v":64,"x":8,"y":23},{"v":251,"x":9,"y":23},{"v":253,"x":10,"y":23},{"v":220,"x":11,"y":23},{"v":0,"x":12,"y":23},{"v":0,"x":13,"y":23},{"v":0,"x":14,"y":23},{"v":0,"x":15,"y":23},{"v":0,"x":16,"y":23},{"v":0,"x":17,"y":23},{"v":0,"x":18,"y":23},{"v":0,"x":19,"y":23},{"v":0,"x":20,"y":23},{"v":0,"x":21,"y":23},{"v":0,"x":22,"y":23},{"v":0,"x":23,"y":23},{"v":0,"x":24,"y":23},{"v":0,"x":25,"y":23},{"v":0,"x":26,"y":23},{"v":0,"x":27,"y":23},{"v":0,"x":0,"y":24},{"v":0,"x":1,"y":24},{"v":0,"x":2,"y":24},{"v":0,"x":3,"y":24},{"v":0,"x":4,"y":24},{"v":0,"x":5,"y":24},{"v":0,"x":6,"y":24},{"v":0,"x":7,"y":24},{"v":24,"x":8,"y":24},{"v":193,"x":9,"y":24},{"v":253,"x":10,"y":24},{"v":220,"x":11,"y":24},{"v":0,"x":12,"y":24},{"v":0,"x":13,"y":24},{"v":0,"x":14,"y":24},{"v":0,"x":15,"y":24},{"v":0,"x":16,"y":24},{"v":0,"x":17,"y":24},{"v":0,"x":18,"y":24},{"v":0,"x":19,"y":24},{"v":0,"x":20,"y":24},{"v":0,"x":21,"y":24},{"v":0,"x":22,"y":24},{"v":0,"x":23,"y":24},{"v":0,"x":24,"y":24},{"v":0,"x":25,"y":24},{"v":0,"x":26,"y":24},{"v":0,"x":27,"y":24},{"v":0,"x":0,"y":25},{"v":0,"x":1,"y":25},{"v":0,"x":2,"y":25},{"v":0,"x":3,"y":25},{"v":0,"x":4,"y":25},{"v":0,"x":5,"y":25},{"v":0,"x":6,"y":25},{"v":0,"x":7,"y":25},{"v":0,"x":8,"y":25},{"v":0,"x":9,"y":25},{"v":0,"x":10,"y":25},{"v":0,"x":11,"y":25},{"v":0,"x":12,"y":25},{"v":0,"x":13,"y":25},{"v":0,"x":14,"y":25},{"v":0,"x":15,"y":25},{"v":0,"x":16,"y":25},{"v":0,"x":17,"y":25},{"v":0,"x":18,"y":25},{"v":0,"x":19,"y":25},{"v":0,"x":20,"y":25},{"v":0,"x":21,"y":25},{"v":0,"x":22,"y":25},{"v":0,"x":23,"y":25},{"v":0,"x":24,"y":25},{"v":0,"x":25,"y":25},{"v":0,"x":26,"y":25},{"v":0,"x":27,"y":25},{"v":0,"x":0,"y":26},{"v":0,"x":1,"y":26},{"v":0,"x":2,"y":26},{"v":0,"x":3,"y":26},{"v":0,"x":4,"y":26},{"v":0,"x":5,"y":26},{"v":0,"x":6,"y":26},{"v":0,"x":7,"y":26},{"v":0,"x":8,"y":26},{"v":0,"x":9,"y":26},{"v":0,"x":10,"y":26},{"v":0,"x":11,"y":26},{"v":0,"x":12,"y":26},{"v":0,"x":13,"y":26},{"v":0,"x":14,"y":26},{"v":0,"x":15,"y":26},{"v":0,"x":16,"y":26},{"v":0,"x":17,"y":26},{"v":0,"x":18,"y":26},{"v":0,"x":19,"y":26},{"v":0,"x":20,"y":26},{"v":0,"x":21,"y":26},{"v":0,"x":22,"y":26},{"v":0,"x":23,"y":26},{"v":0,"x":24,"y":26},{"v":0,"x":25,"y":26},{"v":0,"x":26,"y":26},{"v":0,"x":27,"y":26},{"v":0,"x":0,"y":27},{"v":0,"x":1,"y":27},{"v":0,"x":2,"y":27},{"v":0,"x":3,"y":27},{"v":0,"x":4,"y":27},{"v":0,"x":5,"y":27},{"v":0,"x":6,"y":27},{"v":0,"x":7,"y":27},{"v":0,"x":8,"y":27},{"v":0,"x":9,"y":27},{"v":0,"x":10,"y":27},{"v":0,"x":11,"y":27},{"v":0,"x":12,"y":27},{"v":0,"x":13,"y":27},{"v":0,"x":14,"y":27},{"v":0,"x":15,"y":27},{"v":0,"x":16,"y":27},{"v":0,"x":17,"y":27},{"v":0,"x":18,"y":27},{"v":0,"x":19,"y":27},{"v":0,"x":20,"y":27},{"v":0,"x":21,"y":27},{"v":0,"x":22,"y":27},{"v":0,"x":23,"y":27},{"v":0,"x":24,"y":27},{"v":0,"x":25,"y":27},{"v":0,"x":26,"y":27},{"v":0,"x":27,"y":27}]},"encoding":{"color":{"field":"v","legend":null,"scale":{"reverse":true,"scheme":"greys"},"type":"quantitative"},"x":{"axis":null,"field":"x","type":"ordinal"},"y":{"axis":null,"field":"y","type":"ordinal"}},"height":60,"mark":"rect","width":60},{"data":{"values":[{"v":0,"x":0,"y":0},{"v":0,"x":1,"y":0},{"v":0,"x":2,"y":0},{"v":0,"x":3,"y":0},{"v":0,"x":4,"y":0},{"v":0,"x":5,"y":0},{"v":0,"x":6,"y":0},{"v":0,"x":7,"y":0},{"v":0,"x":8,"y":0},{"v":0,"x":9,"y":0},{"v":0,"x":10,"y":0},{"v":0,"x":11,"y":0},{"v":0,"x":12,"y":0},{"v":0,"x":13,"y":0},{"v":0,"x":14,"y":0},{"v":0,"x":15,"y":0},{"v":0,"x":16,"y":0},{"v":0,"x":17,"y":0},{"v":0,"x":18,"y":0},{"v":0,"x":19,"y":0},{"v":0,"x":20,"y":0},{"v":0,"x":21,"y":0},{"v":0,"x":22,"y":0},{"v":0,"x":23,"y":0},{"v":0,"x":24,"y":0},{"v":0,"x":25,"y":0},{"v":0,"x":26,"y":0},{"v":0,"x":27,"y":0},{"v":0,"x":0,"y":1},{"v":0,"x":1,"y":1},{"v":0,"x":2,"y":1},{"v":0,"x":3,"y":1},{"v":0,"x":4,"y":1},{"v":0,"x":5,"y":1},{"v":0,"x":6,"y":1},{"v":0,"x":7,"y":1},{"v":0,"x":8,"y":1},{"v":0,"x":9,"y":1},{"v":0,"x":10,"y":1},{"v":0,"x":11,"y":1},{"v":0,"x":12,"y":1},{"v":0,"x":13,"y":1},{"v":0,"x":14,"y":1},{"v":0,"x":15,"y":1},{"v":0,"x":16,"y":1},{"v":0,"x":17,"y":1},{"v":0,"x":18,"y":1},{"v":0,"x":19,"y":1},{"v":0,"x":20,"y":1},{"v":0,"x":21,"y":1},{"v":0,"x":22,"y":1},{"v":0,"x":23,"y":1},{"v":0,"x":24,"y":1},{"v":0,"x":25,"y":1},{"v":0,"x":26,"y":1},{"v":0,"x":27,"y":1},{"v":0,"x":0,"y":2},{"v":0,"x":1,"y":2},{"v":0,"x":2,"y":2},{"v":0,"x":3,"y":2},{"v":0,"x":4,"y":2},{"v":0,"x":5,"y":2},{"v":0,"x":6,"y":2},{"v":0,"x":7,"y":2},{"v":0,"x":8,"y":2},{"v":0,"x":9,"y":2},{"v":0,"x":10,"y":2},{"v":0,"x":11,"y":2},{"v":0,"x":12,"y":2},{"v":0,"x":13,"y":2},{"v":0,"x":14,"y":2},{"v":0,"x":15,"y":2},{"v":0,"x":16,"y":2},{"v":0,"x":17,"y":2},{"v":0,"x":18,"y":2},{"v":0,"x":19,"y":2},{"v":0,"x":20,"y":2},{"v":0,"x":21,"y":2},{"v":0,"x":22,"y":2},{"v":0,"x":23,"y":2},{"v":0,"x":24,"y":2},{"v":0,"x":25,"y":2},{"v":0,"x":26,"y":2},{"v":0,"x":27,"y":2},{"v":0,"x":0,"y":3},{"v":0,"x":1,"y":3},{"v":0,"x":2,"y":3},{"v":0,"x":3,"y":3},{"v":0,"x":4,"y":3},{"v":0,"x":5,"y":3},{"v":0,"x":6,"y":3},{"v":0,"x":7,"y":3},{"v":0,"x":8,"y":3},{"v":0,"x":9,"y":3},{"v":0,"x":10,"y":3},{"v":0,"x":11,"y":3},{"v":0,"x":12,"y":3},{"v":0,"x":13,"y":3},{"v":0,"x":14,"y":3},{"v":0,"x":15,"y":3},{"v":0,"x":16,"y":3},{"v":0,"x":17,"y":3},{"v":0,"x":18,"y":3},{"v":0,"x":19,"y":3},{"v":0,"x":20,"y":3},{"v":0,"x":21,"y":3},{"v":0,"x":22,"y":3},{"v":0,"x":23,"y":3},{"v":0,"x":24,"y":3},{"v":0,"x":25,"y":3},{"v":0,"x":26,"y":3},{"v":0,"x":27,"y":3},{"v":0,"x":0,"y":4},{"v":0,"x":1,"y":4},{"v":0,"x":2,"y":4},{"v":0,"x":3,"y":4},{"v":0,"x":4,"y":4},{"v":0,"x":5,"y":4},{"v":0,"x":6,"y":4},{"v":0,"x":7,"y":4},{"v":0,"x":8,"y":4},{"v":0,"x":9,"y":4},{"v":0,"x":10,"y":4},{"v":0,"x":11,"y":4},{"v":0,"x":12,"y":4},{"v":0,"x":13,"y":4},{"v":0,"x":14,"y":4},{"v":0,"x":15,"y":4},{"v":0,"x":16,"y":4},{"v":0,"x":17,"y":4},{"v":0,"x":18,"y":4},{"v":0,"x":19,"y":4},{"v":0,"x":20,"y":4},{"v":0,"x":21,"y":4},{"v":0,"x":22,"y":4},{"v":0,"x":23,"y":4},{"v":0,"x":24,"y":4},{"v":0,"x":25,"y":4},{"v":0,"x":26,"y":4},{"v":0,"x":27,"y":4},{"v":0,"x":0,"y":5},{"v":0,"x":1,"y":5},{"v":0,"x":2,"y":5},{"v":0,"x":3,"y":5},{"v":0,"x":4,"y":5},{"v":0,"x":5,"y":5},{"v":0,"x":6,"y":5},{"v":0,"x":7,"y":5},{"v":0,"x":8,"y":5},{"v":0,"x":9,"y":5},{"v":0,"x":10,"y":5},{"v":0,"x":11,"y":5},{"v":0,"x":12,"y":5},{"v":0,"x":13,"y":5},{"v":0,"x":14,"y":5},{"v":0,"x":15,"y":5},{"v":0,"x":16,"y":5},{"v":0,"x":17,"y":5},{"v":0,"x":18,"y":5},{"v":0,"x":19,"y":5},{"v":0,"x":20,"y":5},{"v":0,"x":21,"y":5},{"v":0,"x":22,"y":5},{"v":0,"x":23,"y":5},{"v":0,"x":24,"y":5},{"v":0,"x":25,"y":5},{"v":0,"x":26,"y":5},{"v":0,"x":27,"y":5},{"v":0,"x":0,"y":6},{"v":0,"x":1,"y":6},{"v":0,"x":2,"y":6},{"v":0,"x":3,"y":6},{"v":0,"x":4,"y":6},{"v":0,"x":5,"y":6},{"v":0,"x":6,"y":6},{"v":0,"x":7,"y":6},{"v":0,"x":8,"y":6},{"v":0,"x":9,"y":6},{"v":0,"x":10,"y":6},{"v":0,"x":11,"y":6},{"v":0,"x":12,"y":6},{"v":0,"x":13,"y":6},{"v":0,"x":14,"y":6},{"v":0,"x":15,"y":6},{"v":0,"x":16,"y":6},{"v":0,"x":17,"y":6},{"v":0,"x":18,"y":6},{"v":0,"x":19,"y":6},{"v":0,"x":20,"y":6},{"v":0,"x":21,"y":6},{"v":0,"x":22,"y":6},{"v":0,"x":23,"y":6},{"v":0,"x":24,"y":6},{"v":0,"x":25,"y":6},{"v":0,"x":26,"y":6},{"v":0,"x":27,"y":6},{"v":0,"x":0,"y":7},{"v":0,"x":1,"y":7},{"v":0,"x":2,"y":7},{"v":0,"x":3,"y":7},{"v":0,"x":4,"y":7},{"v":0,"x":5,"y":7},{"v":0,"x":6,"y":7},{"v":0,"x":7,"y":7},{"v":0,"x":8,"y":7},{"v":0,"x":9,"y":7},{"v":0,"x":10,"y":7},{"v":0,"x":11,"y":7},{"v":55,"x":12,"y":7},{"v":148,"x":13,"y":7},{"v":210,"x":14,"y":7},{"v":253,"x":15,"y":7},{"v":253,"x":16,"y":7},{"v":113,"x":17,"y":7},{"v":87,"x":18,"y":7},{"v":148,"x":19,"y":7},{"v":55,"x":20,"y":7},{"v":0,"x":21,"y":7},{"v":0,"x":22,"y":7},{"v":0,"x":23,"y":7},{"v":0,"x":24,"y":7},{"v":0,"x":25,"y":7},{"v":0,"x":26,"y":7},{"v":0,"x":27,"y":7},{"v":0,"x":0,"y":8},{"v":0,"x":1,"y":8},{"v":0,"x":2,"y":8},{"v":0,"x":3,"y":8},{"v":0,"x":4,"y":8},{"v":0,"x":5,"y":8},{"v":0,"x":6,"y":8},{"v":0,"x":7,"y":8},{"v":0,"x":8,"y":8},{"v":0,"x":9,"y":8},{"v":0,"x":10,"y":8},{"v":87,"x":11,"y":8},{"v":232,"x":12,"y":8},{"v":252,"x":13,"y":8},{"v":253,"x":14,"y":8},{"v":189,"x":15,"y":8},{"v":210,"x":16,"y":8},{"v":252,"x":17,"y":8},{"v":252,"x":18,"y":8},{"v":253,"x":19,"y":8},{"v":168,"x":20,"y":8},{"v":0,"x":21,"y":8},{"v":0,"x":22,"y":8},{"v":0,"x":23,"y":8},{"v":0,"x":24,"y":8},{"v":0,"x":25,"y":8},{"v":0,"x":26,"y":8},{"v":0,"x":27,"y":8},{"v":0,"x":0,"y":9},{"v":0,"x":1,"y":9},{"v":0,"x":2,"y":9},{"v":0,"x":3,"y":9},{"v":0,"x":4,"y":9},{"v":0,"x":5,"y":9},{"v":0,"x":6,"y":9},{"v":0,"x":7,"y":9},{"v":0,"x":8,"y":9},{"v":4,"x":9,"y":9},{"v":57,"x":10,"y":9},{"v":242,"x":11,"y":9},{"v":252,"x":12,"y":9},{"v":190,"x":13,"y":9},{"v":65,"x":14,"y":9},{"v":5,"x":15,"y":9},{"v":12,"x":16,"y":9},{"v":182,"x":17,"y":9},{"v":252,"x":18,"y":9},{"v":253,"x":19,"y":9},{"v":116,"x":20,"y":9},{"v":0,"x":21,"y":9},{"v":0,"x":22,"y":9},{"v":0,"x":23,"y":9},{"v":0,"x":24,"y":9},{"v":0,"x":25,"y":9},{"v":0,"x":26,"y":9},{"v":0,"x":27,"y":9},{"v":0,"x":0,"y":10},{"v":0,"x":1,"y":10},{"v":0,"x":2,"y":10},{"v":0,"x":3,"y":10},{"v":0,"x":4,"y":10},{"v":0,"x":5,"y":10},{"v":0,"x":6,"y":10},{"v":0,"x":7,"y":10},{"v":0,"x":8,"y":10},{"v":96,"x":9,"y":10},{"v":252,"x":10,"y":10},{"v":252,"x":11,"y":10},{"v":183,"x":12,"y":10},{"v":14,"x":13,"y":10},{"v":0,"x":14,"y":10},{"v":0,"x":15,"y":10},{"v":92,"x":16,"y":10},{"v":252,"x":17,"y":10},{"v":252,"x":18,"y":10},{"v":225,"x":19,"y":10},{"v":21,"x":20,"y":10},{"v":0,"x":21,"y":10},{"v":0,"x":22,"y":10},{"v":0,"x":23,"y":10},{"v":0,"x":24,"y":10},{"v":0,"x":25,"y":10},{"v":0,"x":26,"y":10},{"v":0,"x":27,"y":10},{"v":0,"x":0,"y":11},{"v":0,"x":1,"y":11},{"v":0,"x":2,"y":11},{"v":0,"x":3,"y":11},{"v":0,"x":4,"y":11},{"v":0,"x":5,"y":11},{"v":0,"x":6,"y":11},{"v":0,"x":7,"y":11},{"v":132,"x":8,"y":11},{"v":253,"x":9,"y":11},{"v":252,"x":10,"y":11},{"v":146,"x":11,"y":11},{"v":14,"x":12,"y":11},{"v":0,"x":13,"y":11},{"v":0,"x":14,"y":11},{"v":0,"x":15,"y":11},{"v":215,"x":16,"y":11},{"v":252,"x":17,"y":11},{"v":252,"x":18,"y":11},{"v":79,"x":19,"y":11},{"v":0,"x":20,"y":11},{"v":0,"x":21,"y":11},{"v":0,"x":22,"y":11},{"v":0,"x":23,"y":11},{"v":0,"x":24,"y":11},{"v":0,"x":25,"y":11},{"v":0,"x":26,"y":11},{"v":0,"x":27,"y":11},{"v":0,"x":0,"y":12},{"v":0,"x":1,"y":12},{"v":0,"x":2,"y":12},{"v":0,"x":3,"y":12},{"v":0,"x":4,"y":12},{"v":0,"x":5,"y":12},{"v":0,"x":6,"y":12},{"v":126,"x":7,"y":12},{"v":253,"x":8,"y":12},{"v":247,"x":9,"y":12},{"v":176,"x":10,"y":12},{"v":9,"x":11,"y":12},{"v":0,"x":12,"y":12},{"v":0,"x":13,"y":12},{"v":8,"x":14,"y":12},{"v":78,"x":15,"y":12},{"v":245,"x":16,"y":12},{"v":253,"x":17,"y":12},{"v":129,"x":18,"y":12},{"v":0,"x":19,"y":12},{"v":0,"x":20,"y":12},{"v":0,"x":21,"y":12},{"v":0,"x":22,"y":12},{"v":0,"x":23,"y":12},{"v":0,"x":24,"y":12},{"v":0,"x":25,"y":12},{"v":0,"x":26,"y":12},{"v":0,"x":27,"y":12},{"v":0,"x":0,"y":13},{"v":0,"x":1,"y":13},{"v":0,"x":2,"y":13},{"v":0,"x":3,"y":13},{"v":0,"x":4,"y":13},{"v":0,"x":5,"y":13},{"v":16,"x":6,"y":13},{"v":232,"x":7,"y":13},{"v":252,"x":8,"y":13},{"v":176,"x":9,"y":13},{"v":0,"x":10,"y":13},{"v":0,"x":11,"y":13},{"v":0,"x":12,"y":13},{"v":36,"x":13,"y":13},{"v":201,"x":14,"y":13},{"v":252,"x":15,"y":13},{"v":252,"x":16,"y":13},{"v":169,"x":17,"y":13},{"v":11,"x":18,"y":13},{"v":0,"x":19,"y":13},{"v":0,"x":20,"y":13},{"v":0,"x":21,"y":13},{"v":0,"x":22,"y":13},{"v":0,"x":23,"y":13},{"v":0,"x":24,"y":13},{"v":0,"x":25,"y":13},{"v":0,"x":26,"y":13},{"v":0,"x":27,"y":13},{"v":0,"x":0,"y":14},{"v":0,"x":1,"y":14},{"v":0,"x":2,"y":14},{"v":0,"x":3,"y":14},{"v":0,"x":4,"y":14},{"v":0,"x":5,"y":14},{"v":22,"x":6,"y":14},{"v":252,"x":7,"y":14},{"v":252,"x":8,"y":14},{"v":30,"x":9,"y":14},{"v":22,"x":10,"y":14},{"v":119,"x":11,"y":14},{"v":197,"x":12,"y":14},{"v":241,"x":13,"y":14},{"v":253,"x":14,"y":14},{"v":252,"x":15,"y":14},{"v":251,"x":16,"y":14},{"v":77,"x":17,"y":14},{"v":0,"x":18,"y":14},{"v":0,"x":19,"y":14},{"v":0,"x":20,"y":14},{"v":0,"x":21,"y":14},{"v":0,"x":22,"y":14},{"v":0,"x":23,"y":14},{"v":0,"x":24,"y":14},{"v":0,"x":25,"y":14},{"v":0,"x":26,"y":14},{"v":0,"x":27,"y":14},{"v":0,"x":0,"y":15},{"v":0,"x":1,"y":15},{"v":0,"x":2,"y":15},{"v":0,"x":3,"y":15},{"v":0,"x":4,"y":15},{"v":0,"x":5,"y":15},{"v":16,"x":6,"y":15},{"v":231,"x":7,"y":15},{"v":252,"x":8,"y":15},{"v":253,"x":9,"y":15},{"v":252,"x":10,"y":15},{"v":252,"x":11,"y":15},{"v":252,"x":12,"y":15},{"v":226,"x":13,"y":15},{"v":227,"x":14,"y":15},{"v":252,"x":15,"y":15},{"v":231,"x":16,"y":15},{"v":0,"x":17,"y":15},{"v":0,"x":18,"y":15},{"v":0,"x":19,"y":15},{"v":0,"x":20,"y":15},{"v":0,"x":21,"y":15},{"v":0,"x":22,"y":15},{"v":0,"x":23,"y":15},{"v":0,"x":24,"y":15},{"v":0,"x":25,"y":15},{"v":0,"x":26,"y":15},{"v":0,"x":27,"y":15},{"v":0,"x":0,"y":16},{"v":0,"x":1,"y":16},{"v":0,"x":2,"y":16},{"v":0,"x":3,"y":16},{"v":0,"x":4,"y":16},{"v":0,"x":5,"y":16},{"v":0,"x":6,"y":16},{"v":55,"x":7,"y":16},{"v":235,"x":8,"y":16},{"v":253,"x":9,"y":16},{"v":217,"x":10,"y":16},{"v":138,"x":11,"y":16},{"v":42,"x":12,"y":16},{"v":24,"x":13,"y":16},{"v":192,"x":14,"y":16},{"v":252,"x":15,"y":16},{"v":143,"x":16,"y":16},{"v":0,"x":17,"y":16},{"v":0,"x":18,"y":16},{"v":0,"x":19,"y":16},{"v":0,"x":20,"y":16},{"v":0,"x":21,"y":16},{"v":0,"x":22,"y":16},{"v":0,"x":23,"y":16},{"v":0,"x":24,"y":16},{"v":0,"x":25,"y":16},{"v":0,"x":26,"y":16},{"v":0,"x":27,"y":16},{"v":0,"x":0,"y":17},{"v":0,"x":1,"y":17},{"v":0,"x":2,"y":17},{"v":0,"x":3,"y":17},{"v":0,"x":4,"y":17},{"v":0,"x":5,"y":17},{"v":0,"x":6,"y":17},{"v":0,"x":7,"y":17},{"v":0,"x":8,"y":17},{"v":0,"x":9,"y":17},{"v":0,"x":10,"y":17},{"v":0,"x":11,"y":17},{"v":0,"x":12,"y":17},{"v":62,"x":13,"y":17},{"v":255,"x":14,"y":17},{"v":253,"x":15,"y":17},{"v":109,"x":16,"y":17},{"v":0,"x":17,"y":17},{"v":0,"x":18,"y":17},{"v":0,"x":19,"y":17},{"v":0,"x":20,"y":17},{"v":0,"x":21,"y":17},{"v":0,"x":22,"y":17},{"v":0,"x":23,"y":17},{"v":0,"x":24,"y":17},{"v":0,"x":25,"y":17},{"v":0,"x":26,"y":17},{"v":0,"x":27,"y":17},{"v":0,"x":0,"y":18},{"v":0,"x":1,"y":18},{"v":0,"x":2,"y":18},{"v":0,"x":3,"y":18},{"v":0,"x":4,"y":18},{"v":0,"x":5,"y":18},{"v":0,"x":6,"y":18},{"v":0,"x":7,"y":18},{"v":0,"x":8,"y":18},{"v":0,"x":9,"y":18},{"v":0,"x":10,"y":18},{"v":0,"x":11,"y":18},{"v":0,"x":12,"y":18},{"v":71,"x":13,"y":18},{"v":253,"x":14,"y":18},{"v":252,"x":15,"y":18},{"v":21,"x":16,"y":18},{"v":0,"x":17,"y":18},{"v":0,"x":18,"y":18},{"v":0,"x":19,"y":18},{"v":0,"x":20,"y":18},{"v":0,"x":21,"y":18},{"v":0,"x":22,"y":18},{"v":0,"x":23,"y":18},{"v":0,"x":24,"y":18},{"v":0,"x":25,"y":18},{"v":0,"x":26,"y":18},{"v":0,"x":27,"y":18},{"v":0,"x":0,"y":19},{"v":0,"x":1,"y":19},{"v":0,"x":2,"y":19},{"v":0,"x":3,"y":19},{"v":0,"x":4,"y":19},{"v":0,"x":5,"y":19},{"v":0,"x":6,"y":19},{"v":0,"x":7,"y":19},{"v":0,"x":8,"y":19},{"v":0,"x":9,"y":19},{"v":0,"x":10,"y":19},{"v":0,"x":11,"y":19},{"v":0,"x":12,"y":19},{"v":0,"x":13,"y":19},{"v":253,"x":14,"y":19},{"v":252,"x":15,"y":19},{"v":21,"x":16,"y":19},{"v":0,"x":17,"y":19},{"v":0,"x":18,"y":19},{"v":0,"x":19,"y":19},{"v":0,"x":20,"y":19},{"v":0,"x":21,"y":19},{"v":0,"x":22,"y":19},{"v":0,"x":23,"y":19},{"v":0,"x":24,"y":19},{"v":0,"x":25,"y":19},{"v":0,"x":26,"y":19},{"v":0,"x":27,"y":19},{"v":0,"x":0,"y":20},{"v":0,"x":1,"y":20},{"v":0,"x":2,"y":20},{"v":0,"x":3,"y":20},{"v":0,"x":4,"y":20},{"v":0,"x":5,"y":20},{"v":0,"x":6,"y":20},{"v":0,"x":7,"y":20},{"v":0,"x":8,"y":20},{"v":0,"x":9,"y":20},{"v":0,"x":10,"y":20},{"v":0,"x":11,"y":20},{"v":0,"x":12,"y":20},{"v":71,"x":13,"y":20},{"v":253,"x":14,"y":20},{"v":252,"x":15,"y":20},{"v":21,"x":16,"y":20},{"v":0,"x":17,"y":20},{"v":0,"x":18,"y":20},{"v":0,"x":19,"y":20},{"v":0,"x":20,"y":20},{"v":0,"x":21,"y":20},{"v":0,"x":22,"y":20},{"v":0,"x":23,"y":20},{"v":0,"x":24,"y":20},{"v":0,"x":25,"y":20},{"v":0,"x":26,"y":20},{"v":0,"x":27,"y":20},{"v":0,"x":0,"y":21},{"v":0,"x":1,"y":21},{"v":0,"x":2,"y":21},{"v":0,"x":3,"y":21},{"v":0,"x":4,"y":21},{"v":0,"x":5,"y":21},{"v":0,"x":6,"y":21},{"v":0,"x":7,"y":21},{"v":0,"x":8,"y":21},{"v":0,"x":9,"y":21},{"v":0,"x":10,"y":21},{"v":0,"x":11,"y":21},{"v":0,"x":12,"y":21},{"v":106,"x":13,"y":21},{"v":253,"x":14,"y":21},{"v":252,"x":15,"y":21},{"v":21,"x":16,"y":21},{"v":0,"x":17,"y":21},{"v":0,"x":18,"y":21},{"v":0,"x":19,"y":21},{"v":0,"x":20,"y":21},{"v":0,"x":21,"y":21},{"v":0,"x":22,"y":21},{"v":0,"x":23,"y":21},{"v":0,"x":24,"y":21},{"v":0,"x":25,"y":21},{"v":0,"x":26,"y":21},{"v":0,"x":27,"y":21},{"v":0,"x":0,"y":22},{"v":0,"x":1,"y":22},{"v":0,"x":2,"y":22},{"v":0,"x":3,"y":22},{"v":0,"x":4,"y":22},{"v":0,"x":5,"y":22},{"v":0,"x":6,"y":22},{"v":0,"x":7,"y":22},{"v":0,"x":8,"y":22},{"v":0,"x":9,"y":22},{"v":0,"x":10,"y":22},{"v":0,"x":11,"y":22},{"v":0,"x":12,"y":22},{"v":45,"x":13,"y":22},{"v":255,"x":14,"y":22},{"v":253,"x":15,"y":22},{"v":21,"x":16,"y":22},{"v":0,"x":17,"y":22},{"v":0,"x":18,"y":22},{"v":0,"x":19,"y":22},{"v":0,"x":20,"y":22},{"v":0,"x":21,"y":22},{"v":0,"x":22,"y":22},{"v":0,"x":23,"y":22},{"v":0,"x":24,"y":22},{"v":0,"x":25,"y":22},{"v":0,"x":26,"y":22},{"v":0,"x":27,"y":22},{"v":0,"x":0,"y":23},{"v":0,"x":1,"y":23},{"v":0,"x":2,"y":23},{"v":0,"x":3,"y":23},{"v":0,"x":4,"y":23},{"v":0,"x":5,"y":23},{"v":0,"x":6,"y":23},{"v":0,"x":7,"y":23},{"v":0,"x":8,"y":23},{"v":0,"x":9,"y":23},{"v":0,"x":10,"y":23},{"v":0,"x":11,"y":23},{"v":0,"x":12,"y":23},{"v":0,"x":13,"y":23},{"v":218,"x":14,"y":23},{"v":252,"x":15,"y":23},{"v":56,"x":16,"y":23},{"v":0,"x":17,"y":23},{"v":0,"x":18,"y":23},{"v":0,"x":19,"y":23},{"v":0,"x":20,"y":23},{"v":0,"x":21,"y":23},{"v":0,"x":22,"y":23},{"v":0,"x":23,"y":23},{"v":0,"x":24,"y":23},{"v":0,"x":25,"y":23},{"v":0,"x":26,"y":23},{"v":0,"x":27,"y":23},{"v":0,"x":0,"y":24},{"v":0,"x":1,"y":24},{"v":0,"x":2,"y":24},{"v":0,"x":3,"y":24},{"v":0,"x":4,"y":24},{"v":0,"x":5,"y":24},{"v":0,"x":6,"y":24},{"v":0,"x":7,"y":24},{"v":0,"x":8,"y":24},{"v":0,"x":9,"y":24},{"v":0,"x":10,"y":24},{"v":0,"x":11,"y":24},{"v":0,"x":12,"y":24},{"v":0,"x":13,"y":24},{"v":96,"x":14,"y":24},{"v":252,"x":15,"y":24},{"v":189,"x":16,"y":24},{"v":42,"x":17,"y":24},{"v":0,"x":18,"y":24},{"v":0,"x":19,"y":24},{"v":0,"x":20,"y":24},{"v":0,"x":21,"y":24},{"v":0,"x":22,"y":24},{"v":0,"x":23,"y":24},{"v":0,"x":24,"y":24},{"v":0,"x":25,"y":24},{"v":0,"x":26,"y":24},{"v":0,"x":27,"y":24},{"v":0,"x":0,"y":25},{"v":0,"x":1,"y":25},{"v":0,"x":2,"y":25},{"v":0,"x":3,"y":25},{"v":0,"x":4,"y":25},{"v":0,"x":5,"y":25},{"v":0,"x":6,"y":25},{"v":0,"x":7,"y":25},{"v":0,"x":8,"y":25},{"v":0,"x":9,"y":25},{"v":0,"x":10,"y":25},{"v":0,"x":11,"y":25},{"v":0,"x":12,"y":25},{"v":0,"x":13,"y":25},{"v":14,"x":14,"y":25},{"v":184,"x":15,"y":25},{"v":252,"x":16,"y":25},{"v":170,"x":17,"y":25},{"v":11,"x":18,"y":25},{"v":0,"x":19,"y":25},{"v":0,"x":20,"y":25},{"v":0,"x":21,"y":25},{"v":0,"x":22,"y":25},{"v":0,"x":23,"y":25},{"v":0,"x":24,"y":25},{"v":0,"x":25,"y":25},{"v":0,"x":26,"y":25},{"v":0,"x":27,"y":25},{"v":0,"x":0,"y":26},{"v":0,"x":1,"y":26},{"v":0,"x":2,"y":26},{"v":0,"x":3,"y":26},{"v":0,"x":4,"y":26},{"v":0,"x":5,"y":26},{"v":0,"x":6,"y":26},{"v":0,"x":7,"y":26},{"v":0,"x":8,"y":26},{"v":0,"x":9,"y":26},{"v":0,"x":10,"y":26},{"v":0,"x":11,"y":26},{"v":0,"x":12,"y":26},{"v":0,"x":13,"y":26},{"v":0,"x":14,"y":26},{"v":14,"x":15,"y":26},{"v":147,"x":16,"y":26},{"v":252,"x":17,"y":26},{"v":42,"x":18,"y":26},{"v":0,"x":19,"y":26},{"v":0,"x":20,"y":26},{"v":0,"x":21,"y":26},{"v":0,"x":22,"y":26},{"v":0,"x":23,"y":26},{"v":0,"x":24,"y":26},{"v":0,"x":25,"y":26},{"v":0,"x":26,"y":26},{"v":0,"x":27,"y":26},{"v":0,"x":0,"y":27},{"v":0,"x":1,"y":27},{"v":0,"x":2,"y":27},{"v":0,"x":3,"y":27},{"v":0,"x":4,"y":27},{"v":0,"x":5,"y":27},{"v":0,"x":6,"y":27},{"v":0,"x":7,"y":27},{"v":0,"x":8,"y":27},{"v":0,"x":9,"y":27},{"v":0,"x":10,"y":27},{"v":0,"x":11,"y":27},{"v":0,"x":12,"y":27},{"v":0,"x":13,"y":27},{"v":0,"x":14,"y":27},{"v":0,"x":15,"y":27},{"v":0,"x":16,"y":27},{"v":0,"x":17,"y":27},{"v":0,"x":18,"y":27},{"v":0,"x":19,"y":27},{"v":0,"x":20,"y":27},{"v":0,"x":21,"y":27},{"v":0,"x":22,"y":27},{"v":0,"x":23,"y":27},{"v":0,"x":24,"y":27},{"v":0,"x":25,"y":27},{"v":0,"x":26,"y":27},{"v":0,"x":27,"y":27}]},"encoding":{"color":{"field":"v","legend":null,"scale":{"reverse":true,"scheme":"greys"},"type":"quantitative"},"x":{"axis":null,"field":"x","type":"ordinal"},"y":{"axis":null,"field":"y","type":"ordinal"}},"height":60,"mark":"rect","width":60},{"data":{"values":[{"v":0,"x":0,"y":0},{"v":0,"x":1,"y":0},{"v":0,"x":2,"y":0},{"v":0,"x":3,"y":0},{"v":0,"x":4,"y":0},{"v":0,"x":5,"y":0},{"v":0,"x":6,"y":0},{"v":0,"x":7,"y":0},{"v":0,"x":8,"y":0},{"v":0,"x":9,"y":0},{"v":0,"x":10,"y":0},{"v":0,"x":11,"y":0},{"v":0,"x":12,"y":0},{"v":0,"x":13,"y":0},{"v":0,"x":14,"y":0},{"v":0,"x":15,"y":0},{"v":0,"x":16,"y":0},{"v":0,"x":17,"y":0},{"v":0,"x":18,"y":0},{"v":0,"x":19,"y":0},{"v":0,"x":20,"y":0},{"v":0,"x":21,"y":0},{"v":0,"x":22,"y":0},{"v":0,"x":23,"y":0},{"v":0,"x":24,"y":0},{"v":0,"x":25,"y":0},{"v":0,"x":26,"y":0},{"v":0,"x":27,"y":0},{"v":0,"x":0,"y":1},{"v":0,"x":1,"y":1},{"v":0,"x":2,"y":1},{"v":0,"x":3,"y":1},{"v":0,"x":4,"y":1},{"v":0,"x":5,"y":1},{"v":0,"x":6,"y":1},{"v":0,"x":7,"y":1},{"v":0,"x":8,"y":1},{"v":0,"x":9,"y":1},{"v":0,"x":10,"y":1},{"v":0,"x":11,"y":1},{"v":0,"x":12,"y":1},{"v":0,"x":13,"y":1},{"v":0,"x":14,"y":1},{"v":0,"x":15,"y":1},{"v":0,"x":16,"y":1},{"v":0,"x":17,"y":1},{"v":0,"x":18,"y":1},{"v":0,"x":19,"y":1},{"v":0,"x":20,"y":1},{"v":0,"x":21,"y":1},{"v":0,"x":22,"y":1},{"v":0,"x":23,"y":1},{"v":0,"x":24,"y":1},{"v":0,"x":25,"y":1},{"v":0,"x":26,"y":1},{"v":0,"x":27,"y":1},{"v":0,"x":0,"y":2},{"v":0,"x":1,"y":2},{"v":0,"x":2,"y":2},{"v":0,"x":3,"y":2},{"v":0,"x":4,"y":2},{"v":0,"x":5,"y":2},{"v":0,"x":6,"y":2},{"v":0,"x":7,"y":2},{"v":0,"x":8,"y":2},{"v":0,"x":9,"y":2},{"v":0,"x":10,"y":2},{"v":0,"x":11,"y":2},{"v":0,"x":12,"y":2},{"v":0,"x":13,"y":2},{"v":0,"x":14,"y":2},{"v":0,"x":15,"y":2},{"v":0,"x":16,"y":2},{"v":0,"x":17,"y":2},{"v":0,"x":18,"y":2},{"v":0,"x":19,"y":2},{"v":0,"x":20,"y":2},{"v":0,"x":21,"y":2},{"v":0,"x":22,"y":2},{"v":0,"x":23,"y":2},{"v":0,"x":24,"y":2},{"v":0,"x":25,"y":2},{"v":0,"x":26,"y":2},{"v":0,"x":27,"y":2},{"v":0,"x":0,"y":3},{"v":0,"x":1,"y":3},{"v":0,"x":2,"y":3},{"v":0,"x":3,"y":3},{"v":0,"x":4,"y":3},{"v":0,"x":5,"y":3},{"v":0,"x":6,"y":3},{"v":0,"x":7,"y":3},{"v":0,"x":8,"y":3},{"v":0,"x":9,"y":3},{"v":0,"x":10,"y":3},{"v":0,"x":11,"y":3},{"v":0,"x":12,"y":3},{"v":0,"x":13,"y":3},{"v":0,"x":14,"y":3},{"v":0,"x":15,"y":3},{"v":0,"x":16,"y":3},{"v":0,"x":17,"y":3},{"v":0,"x":18,"y":3},{"v":0,"x":19,"y":3},{"v":0,"x":20,"y":3},{"v":0,"x":21,"y":3},{"v":0,"x":22,"y":3},{"v":0,"x":23,"y":3},{"v":0,"x":24,"y":3},{"v":0,"x":25,"y":3},{"v":0,"x":26,"y":3},{"v":0,"x":27,"y":3},{"v":0,"x":0,"y":4},{"v":0,"x":1,"y":4},{"v":0,"x":2,"y":4},{"v":0,"x":3,"y":4},{"v":0,"x":4,"y":4},{"v":0,"x":5,"y":4},{"v":0,"x":6,"y":4},{"v":0,"x":7,"y":4},{"v":0,"x":8,"y":4},{"v":0,"x":9,"y":4},{"v":0,"x":10,"y":4},{"v":0,"x":11,"y":4},{"v":0,"x":12,"y":4},{"v":0,"x":13,"y":4},{"v":0,"x":14,"y":4},{"v":0,"x":15,"y":4},{"v":0,"x":16,"y":4},{"v":0,"x":17,"y":4},{"v":0,"x":18,"y":4},{"v":0,"x":19,"y":4},{"v":0,"x":20,"y":4},{"v":0,"x":21,"y":4},{"v":0,"x":22,"y":4},{"v":0,"x":23,"y":4},{"v":0,"x":24,"y":4},{"v":0,"x":25,"y":4},{"v":0,"x":26,"y":4},{"v":0,"x":27,"y":4},{"v":0,"x":0,"y":5},{"v":0,"x":1,"y":5},{"v":0,"x":2,"y":5},{"v":0,"x":3,"y":5},{"v":0,"x":4,"y":5},{"v":0,"x":5,"y":5},{"v":0,"x":6,"y":5},{"v":0,"x":7,"y":5},{"v":0,"x":8,"y":5},{"v":0,"x":9,"y":5},{"v":0,"x":10,"y":5},{"v":0,"x":11,"y":5},{"v":0,"x":12,"y":5},{"v":0,"x":13,"y":5},{"v":0,"x":14,"y":5},{"v":13,"x":15,"y":5},{"v":25,"x":16,"y":5},{"v":100,"x":17,"y":5},{"v":122,"x":18,"y":5},{"v":7,"x":19,"y":5},{"v":0,"x":20,"y":5},{"v":0,"x":21,"y":5},{"v":0,"x":22,"y":5},{"v":0,"x":23,"y":5},{"v":0,"x":24,"y":5},{"v":0,"x":25,"y":5},{"v":0,"x":26,"y":5},{"v":0,"x":27,"y":5},{"v":0,"x":0,"y":6},{"v":0,"x":1,"y":6},{"v":0,"x":2,"y":6},{"v":0,"x":3,"y":6},{"v":0,"x":4,"y":6},{"v":0,"x":5,"y":6},{"v":0,"x":6,"y":6},{"v":0,"x":7,"y":6},{"v":0,"x":8,"y":6},{"v":0,"x":9,"y":6},{"v":0,"x":10,"y":6},{"v":0,"x":11,"y":6},{"v":0,"x":12,"y":6},{"v":33,"x":13,"y":6},{"v":151,"x":14,"y":6},{"v":208,"x":15,"y":6},{"v":252,"x":16,"y":6},{"v":252,"x":17,"y":6},{"v":252,"x":18,"y":6},{"v":146,"x":19,"y":6},{"v":0,"x":20,"y":6},{"v":0,"x":21,"y":6},{"v":0,"x":22,"y":6},{"v":0,"x":23,"y":6},{"v":0,"x":24,"y":6},{"v":0,"x":25,"y":6},{"v":0,"x":26,"y":6},{"v":0,"x":27,"y":6},{"v":0,"x":0,"y":7},{"v":0,"x":1,"y":7},{"v":0,"x":2,"y":7},{"v":0,"x":3,"y":7},{"v":0,"x":4,"y":7},{"v":0,"x":5,"y":7},{"v":0,"x":6,"y":7},{"v":0,"x":7,"y":7},{"v":0,"x":8,"y":7},{"v":0,"x":9,"y":7},{"v":0,"x":10,"y":7},{"v":40,"x":11,"y":7},{"v":152,"x":12,"y":7},{"v":244,"x":13,"y":7},{"v":252,"x":14,"y":7},{"v":253,"x":15,"y":7},{"v":224,"x":16,"y":7},{"v":211,"x":17,"y":7},{"v":252,"x":18,"y":7},{"v":232,"x":19,"y":7},{"v":40,"x":20,"y":7},{"v":0,"x":21,"y":7},{"v":0,"x":22,"y":7},{"v":0,"x":23,"y":7},{"v":0,"x":24,"y":7},{"v":0,"x":25,"y":7},{"v":0,"x":26,"y":7},{"v":0,"x":27,"y":7},{"v":0,"x":0,"y":8},{"v":0,"x":1,"y":8},{"v":0,"x":2,"y":8},{"v":0,"x":3,"y":8},{"v":0,"x":4,"y":8},{"v":0,"x":5,"y":8},{"v":0,"x":6,"y":8},{"v":0,"x":7,"y":8},{"v":0,"x":8,"y":8},{"v":15,"x":9,"y":8},{"v":152,"x":10,"y":8},{"v":239,"x":11,"y":8},{"v":252,"x":12,"y":8},{"v":252,"x":13,"y":8},{"v":252,"x":14,"y":8},{"v":216,"x":15,"y":8},{"v":31,"x":16,"y":8},{"v":37,"x":17,"y":8},{"v":252,"x":18,"y":8},{"v":252,"x":19,"y":8},{"v":60,"x":20,"y":8},{"v":0,"x":21,"y":8},{"v":0,"x":22,"y":8},{"v":0,"x":23,"y":8},{"v":0,"x":24,"y":8},{"v":0,"x":25,"y":8},{"v":0,"x":26,"y":8},{"v":0,"x":27,"y":8},{"v":0,"x":0,"y":9},{"v":0,"x":1,"y":9},{"v":0,"x":2,"y":9},{"v":0,"x":3,"y":9},{"v":0,"x":4,"y":9},{"v":0,"x":5,"y":9},{"v":0,"x":6,"y":9},{"v":0,"x":7,"y":9},{"v":0,"x":8,"y":9},{"v":96,"x":9,"y":9},{"v":252,"x":10,"y":9},{"v":252,"x":11,"y":9},{"v":252,"x":12,"y":9},{"v":252,"x":13,"y":9},{"v":217,"x":14,"y":9},{"v":29,"x":15,"y":9},{"v":0,"x":16,"y":9},{"v":37,"x":17,"y":9},{"v":252,"x":18,"y":9},{"v":252,"x":19,"y":9},{"v":60,"x":20,"y":9},{"v":0,"x":21,"y":9},{"v":0,"x":22,"y":9},{"v":0,"x":23,"y":9},{"v":0,"x":24,"y":9},{"v":0,"x":25,"y":9},{"v":0,"x":26,"y":9},{"v":0,"x":27,"y":9},{"v":0,"x":0,"y":10},{"v":0,"x":1,"y":10},{"v":0,"x":2,"y":10},{"v":0,"x":3,"y":10},{"v":0,"x":4,"y":10},{"v":0,"x":5,"y":10},{"v":0,"x":6,"y":10},{"v":0,"x":7,"y":10},{"v":0,"x":8,"y":10},{"v":181,"x":9,"y":10},{"v":252,"x":10,"y":10},{"v":252,"x":11,"y":10},{"v":220,"x":12,"y":10},{"v":167,"x":13,"y":10},{"v":30,"x":14,"y":10},{"v":0,"x":15,"y":10},{"v":0,"x":16,"y":10},{"v":77,"x":17,"y":10},{"v":252,"x":18,"y":10},{"v":252,"x":19,"y":10},{"v":60,"x":20,"y":10},{"v":0,"x":21,"y":10},{"v":0,"x":22,"y":10},{"v":0,"x":23,"y":10},{"v":0,"x":24,"y":10},{"v":0,"x":25,"y":10},{"v":0,"x":26,"y":10},{"v":0,"x":27,"y":10},{"v":0,"x":0,"y":11},{"v":0,"x":1,"y":11},{"v":0,"x":2,"y":11},{"v":0,"x":3,"y":11},{"v":0,"x":4,"y":11},{"v":0,"x":5,"y":11},{"v":0,"x":6,"y":11},{"v":0,"x":7,"y":11},{"v":0,"x":8,"y":11},{"v":26,"x":9,"y":11},{"v":128,"x":10,"y":11},{"v":58,"x":11,"y":11},{"v":22,"x":12,"y":11},{"v":0,"x":13,"y":11},{"v":0,"x":14,"y":11},{"v":0,"x":15,"y":11},{"v":0,"x":16,"y":11},{"v":100,"x":17,"y":11},{"v":252,"x":18,"y":11},{"v":252,"x":19,"y":11},{"v":60,"x":20,"y":11},{"v":0,"x":21,"y":11},{"v":0,"x":22,"y":11},{"v":0,"x":23,"y":11},{"v":0,"x":24,"y":11},{"v":0,"x":25,"y":11},{"v":0,"x":26,"y":11},{"v":0,"x":27,"y":11},{"v":0,"x":0,"y":12},{"v":0,"x":1,"y":12},{"v":0,"x":2,"y":12},{"v":0,"x":3,"y":12},{"v":0,"x":4,"y":12},{"v":0,"x":5,"y":12},{"v":0,"x":6,"y":12},{"v":0,"x":7,"y":12},{"v":0,"x":8,"y":12},{"v":0,"x":9,"y":12},{"v":0,"x":10,"y":12},{"v":0,"x":11,"y":12},{"v":0,"x":12,"y":12},{"v":0,"x":13,"y":12},{"v":0,"x":14,"y":12},{"v":0,"x":15,"y":12},{"v":0,"x":16,"y":12},{"v":157,"x":17,"y":12},{"v":252,"x":18,"y":12},{"v":252,"x":19,"y":12},{"v":60,"x":20,"y":12},{"v":0,"x":21,"y":12},{"v":0,"x":22,"y":12},{"v":0,"x":23,"y":12},{"v":0,"x":24,"y":12},{"v":0,"x":25,"y":12},{"v":0,"x":26,"y":12},{"v":0,"x":27,"y":12},{"v":0,"x":0,"y":13},{"v":0,"x":1,"y":13},{"v":0,"x":2,"y":13},{"v":0,"x":3,"y":13},{"v":0,"x":4,"y":13},{"v":0,"x":5,"y":13},{"v":0,"x":6,"y":13},{"v":0,"x":7,"y":13},{"v":0,"x":8,"y":13},{"v":0,"x":9,"y":13},{"v":0,"x":10,"y":13},{"v":0,"x":11,"y":13},{"v":0,"x":12,"y":13},{"v":110,"x":13,"y":13},{"v":121,"x":14,"y":13},{"v":122,"x":15,"y":13},{"v":121,"x":16,"y":13},{"v":202,"x":17,"y":13},{"v":252,"x":18,"y":13},{"v":194,"x":19,"y":13},{"v":3,"x":20,"y":13},{"v":0,"x":21,"y":13},{"v":0,"x":22,"y":13},{"v":0,"x":23,"y":13},{"v":0,"x":24,"y":13},{"v":0,"x":25,"y":13},{"v":0,"x":26,"y":13},{"v":0,"x":27,"y":13},{"v":0,"x":0,"y":14},{"v":0,"x":1,"y":14},{"v":0,"x":2,"y":14},{"v":0,"x":3,"y":14},{"v":0,"x":4,"y":14},{"v":0,"x":5,"y":14},{"v":0,"x":6,"y":14},{"v":0,"x":7,"y":14},{"v":0,"x":8,"y":14},{"v":0,"x":9,"y":14},{"v":10,"x":10,"y":14},{"v":53,"x":11,"y":14},{"v":179,"x":12,"y":14},{"v":253,"x":13,"y":14},{"v":253,"x":14,"y":14},{"v":255,"x":15,"y":14},{"v":253,"x":16,"y":14},{"v":253,"x":17,"y":14},{"v":228,"x":18,"y":14},{"v":35,"x":19,"y":14},{"v":0,"x":20,"y":14},{"v":0,"x":21,"y":14},{"v":0,"x":22,"y":14},{"v":0,"x":23,"y":14},{"v":0,"x":24,"y":14},{"v":0,"x":25,"y":14},{"v":0,"x":26,"y":14},{"v":0,"x":27,"y":14},{"v":0,"x":0,"y":15},{"v":0,"x":1,"y":15},{"v":0,"x":2,"y":15},{"v":0,"x":3,"y":15},{"v":0,"x":4,"y":15},{"v":0,"x":5,"y":15},{"v":0,"x":6,"y":15},{"v":0,"x":7,"y":15},{"v":5,"x":8,"y":15},{"v":54,"x":9,"y":15},{"v":227,"x":10,"y":15},{"v":252,"x":11,"y":15},{"v":243,"x":12,"y":15},{"v":228,"x":13,"y":15},{"v":170,"x":14,"y":15},{"v":242,"x":15,"y":15},{"v":252,"x":16,"y":15},{"v":252,"x":17,"y":15},{"v":231,"x":18,"y":15},{"v":117,"x":19,"y":15},{"v":6,"x":20,"y":15},{"v":0,"x":21,"y":15},{"v":0,"x":22,"y":15},{"v":0,"x":23,"y":15},{"v":0,"x":24,"y":15},{"v":0,"x":25,"y":15},{"v":0,"x":26,"y":15},{"v":0,"x":27,"y":15},{"v":0,"x":0,"y":16},{"v":0,"x":1,"y":16},{"v":0,"x":2,"y":16},{"v":0,"x":3,"y":16},{"v":0,"x":4,"y":16},{"v":0,"x":5,"y":16},{"v":0,"x":6,"y":16},{"v":6,"x":7,"y":16},{"v":78,"x":8,"y":16},{"v":252,"x":9,"y":16},{"v":252,"x":10,"y":16},{"v":125,"x":11,"y":16},{"v":59,"x":12,"y":16},{"v":0,"x":13,"y":16},{"v":18,"x":14,"y":16},{"v":208,"x":15,"y":16},{"v":252,"x":16,"y":16},{"v":252,"x":17,"y":16},{"v":252,"x":18,"y":16},{"v":252,"x":19,"y":16},{"v":87,"x":20,"y":16},{"v":7,"x":21,"y":16},{"v":0,"x":22,"y":16},{"v":0,"x":23,"y":16},{"v":0,"x":24,"y":16},{"v":0,"x":25,"y":16},{"v":0,"x":26,"y":16},{"v":0,"x":27,"y":16},{"v":0,"x":0,"y":17},{"v":0,"x":1,"y":17},{"v":0,"x":2,"y":17},{"v":0,"x":3,"y":17},{"v":0,"x":4,"y":17},{"v":0,"x":5,"y":17},{"v":5,"x":6,"y":17},{"v":135,"x":7,"y":17},{"v":252,"x":8,"y":17},{"v":252,"x":9,"y":17},{"v":180,"x":10,"y":17},{"v":16,"x":11,"y":17},{"v":0,"x":12,"y":17},{"v":21,"x":13,"y":17},{"v":203,"x":14,"y":17},{"v":253,"x":15,"y":17},{"v":247,"x":16,"y":17},{"v":129,"x":17,"y":17},{"v":173,"x":18,"y":17},{"v":252,"x":19,"y":17},{"v":252,"x":20,"y":17},{"v":184,"x":21,"y":17},{"v":66,"x":22,"y":17},{"v":49,"x":23,"y":17},{"v":49,"x":24,"y":17},{"v":0,"x":25,"y":17},{"v":0,"x":26,"y":17},{"v":0,"x":27,"y":17},{"v":0,"x":0,"y":18},{"v":0,"x":1,"y":18},{"v":0,"x":2,"y":18},{"v":0,"x":3,"y":18},{"v":0,"x":4,"y":18},{"v":3,"x":5,"y":18},{"v":136,"x":6,"y":18},{"v":252,"x":7,"y":18},{"v":241,"x":8,"y":18},{"v":106,"x":9,"y":18},{"v":17,"x":10,"y":18},{"v":0,"x":11,"y":18},{"v":53,"x":12,"y":18},{"v":200,"x":13,"y":18},{"v":252,"x":14,"y":18},{"v":216,"x":15,"y":18},{"v":65,"x":16,"y":18},{"v":0,"x":17,"y":18},{"v":14,"x":18,"y":18},{"v":72,"x":19,"y":18},{"v":163,"x":20,"y":18},{"v":241,"x":21,"y":18},{"v":252,"x":22,"y":18},{"v":252,"x":23,"y":18},{"v":223,"x":24,"y":18},{"v":0,"x":25,"y":18},{"v":0,"x":26,"y":18},{"v":0,"x":27,"y":18},{"v":0,"x":0,"y":19},{"v":0,"x":1,"y":19},{"v":0,"x":2,"y":19},{"v":0,"x":3,"y":19},{"v":0,"x":4,"y":19},{"v":105,"x":5,"y":19},{"v":252,"x":6,"y":19},{"v":242,"x":7,"y":19},{"v":88,"x":8,"y":19},{"v":18,"x":9,"y":19},{"v":73,"x":10,"y":19},{"v":170,"x":11,"y":19},{"v":244,"x":12,"y":19},{"v":252,"x":13,"y":19},{"v":126,"x":14,"y":19},{"v":29,"x":15,"y":19},{"v":0,"x":16,"y":19},{"v":0,"x":17,"y":19},{"v":0,"x":18,"y":19},{"v":0,"x":19,"y":19},{"v":0,"x":20,"y":19},{"v":89,"x":21,"y":19},{"v":180,"x":22,"y":19},{"v":180,"x":23,"y":19},{"v":37,"x":24,"y":19},{"v":0,"x":25,"y":19},{"v":0,"x":26,"y":19},{"v":0,"x":27,"y":19},{"v":0,"x":0,"y":20},{"v":0,"x":1,"y":20},{"v":0,"x":2,"y":20},{"v":0,"x":3,"y":20},{"v":0,"x":4,"y":20},{"v":231,"x":5,"y":20},{"v":252,"x":6,"y":20},{"v":245,"x":7,"y":20},{"v":205,"x":8,"y":20},{"v":216,"x":9,"y":20},{"v":252,"x":10,"y":20},{"v":252,"x":11,"y":20},{"v":252,"x":12,"y":20},{"v":124,"x":13,"y":20},{"v":3,"x":14,"y":20},{"v":0,"x":15,"y":20},{"v":0,"x":16,"y":20},{"v":0,"x":17,"y":20},{"v":0,"x":18,"y":20},{"v":0,"x":19,"y":20},{"v":0,"x":20,"y":20},{"v":0,"x":21,"y":20},{"v":0,"x":22,"y":20},{"v":0,"x":23,"y":20},{"v":0,"x":24,"y":20},{"v":0,"x":25,"y":20},{"v":0,"x":26,"y":20},{"v":0,"x":27,"y":20},{"v":0,"x":0,"y":21},{"v":0,"x":1,"y":21},{"v":0,"x":2,"y":21},{"v":0,"x":3,"y":21},{"v":0,"x":4,"y":21},{"v":207,"x":5,"y":21},{"v":252,"x":6,"y":21},{"v":252,"x":7,"y":21},{"v":252,"x":8,"y":21},{"v":252,"x":9,"y":21},{"v":178,"x":10,"y":21},{"v":116,"x":11,"y":21},{"v":36,"x":12,"y":21},{"v":4,"x":13,"y":21},{"v":0,"x":14,"y":21},{"v":0,"x":15,"y":21},{"v":0,"x":16,"y":21},{"v":0,"x":17,"y":21},{"v":0,"x":18,"y":21},{"v":0,"x":19,"y":21},{"v":0,"x":20,"y":21},{"v":0,"x":21,"y":21},{"v":0,"x":22,"y":21},{"v":0,"x":23,"y":21},{"v":0,"x":24,"y":21},{"v":0,"x":25,"y":21},{"v":0,"x":26,"y":21},{"v":0,"x":27,"y":21},{"v":0,"x":0,"y":22},{"v":0,"x":1,"y":22},{"v":0,"x":2,"y":22},{"v":0,"x":3,"y":22},{"v":0,"x":4,"y":22},{"v":13,"x":5,"y":22},{"v":93,"x":6,"y":22},{"v":143,"x":7,"y":22},{"v":121,"x":8,"y":22},{"v":23,"x":9,"y":22},{"v":6,"x":10,"y":22},{"v":0,"x":11,"y":22},{"v":0,"x":12,"y":22},{"v":0,"x":13,"y":22},{"v":0,"x":14,"y":22},{"v":0,"x":15,"y":22},{"v":0,"x":16,"y":22},{"v":0,"x":17,"y":22},{"v":0,"x":18,"y":22},{"v":0,"x":19,"y":22},{"v":0,"x":20,"y":22},{"v":0,"x":21,"y":22},{"v":0,"x":22,"y":22},{"v":0,"x":23,"y":22},{"v":0,"x":24,"y":22},{"v":0,"x":25,"y":22},{"v":0,"x":26,"y":22},{"v":0,"x":27,"y":22},{"v":0,"x":0,"y":23},{"v":0,"x":1,"y":23},{"v":0,"x":2,"y":23},{"v":0,"x":3,"y":23},{"v":0,"x":4,"y":23},{"v":0,"x":5,"y":23},{"v":0,"x":6,"y":23},{"v":0,"x":7,"y":23},{"v":0,"x":8,"y":23},{"v":0,"x":9,"y":23},{"v":0,"x":10,"y":23},{"v":0,"x":11,"y":23},{"v":0,"x":12,"y":23},{"v":0,"x":13,"y":23},{"v":0,"x":14,"y":23},{"v":0,"x":15,"y":23},{"v":0,"x":16,"y":23},{"v":0,"x":17,"y":23},{"v":0,"x":18,"y":23},{"v":0,"x":19,"y":23},{"v":0,"x":20,"y":23},{"v":0,"x":21,"y":23},{"v":0,"x":22,"y":23},{"v":0,"x":23,"y":23},{"v":0,"x":24,"y":23},{"v":0,"x":25,"y":23},{"v":0,"x":26,"y":23},{"v":0,"x":27,"y":23},{"v":0,"x":0,"y":24},{"v":0,"x":1,"y":24},{"v":0,"x":2,"y":24},{"v":0,"x":3,"y":24},{"v":0,"x":4,"y":24},{"v":0,"x":5,"y":24},{"v":0,"x":6,"y":24},{"v":0,"x":7,"y":24},{"v":0,"x":8,"y":24},{"v":0,"x":9,"y":24},{"v":0,"x":10,"y":24},{"v":0,"x":11,"y":24},{"v":0,"x":12,"y":24},{"v":0,"x":13,"y":24},{"v":0,"x":14,"y":24},{"v":0,"x":15,"y":24},{"v":0,"x":16,"y":24},{"v":0,"x":17,"y":24},{"v":0,"x":18,"y":24},{"v":0,"x":19,"y":24},{"v":0,"x":20,"y":24},{"v":0,"x":21,"y":24},{"v":0,"x":22,"y":24},{"v":0,"x":23,"y":24},{"v":0,"x":24,"y":24},{"v":0,"x":25,"y":24},{"v":0,"x":26,"y":24},{"v":0,"x":27,"y":24},{"v":0,"x":0,"y":25},{"v":0,"x":1,"y":25},{"v":0,"x":2,"y":25},{"v":0,"x":3,"y":25},{"v":0,"x":4,"y":25},{"v":0,"x":5,"y":25},{"v":0,"x":6,"y":25},{"v":0,"x":7,"y":25},{"v":0,"x":8,"y":25},{"v":0,"x":9,"y":25},{"v":0,"x":10,"y":25},{"v":0,"x":11,"y":25},{"v":0,"x":12,"y":25},{"v":0,"x":13,"y":25},{"v":0,"x":14,"y":25},{"v":0,"x":15,"y":25},{"v":0,"x":16,"y":25},{"v":0,"x":17,"y":25},{"v":0,"x":18,"y":25},{"v":0,"x":19,"y":25},{"v":0,"x":20,"y":25},{"v":0,"x":21,"y":25},{"v":0,"x":22,"y":25},{"v":0,"x":23,"y":25},{"v":0,"x":24,"y":25},{"v":0,"x":25,"y":25},{"v":0,"x":26,"y":25},{"v":0,"x":27,"y":25},{"v":0,"x":0,"y":26},{"v":0,"x":1,"y":26},{"v":0,"x":2,"y":26},{"v":0,"x":3,"y":26},{"v":0,"x":4,"y":26},{"v":0,"x":5,"y":26},{"v":0,"x":6,"y":26},{"v":0,"x":7,"y":26},{"v":0,"x":8,"y":26},{"v":0,"x":9,"y":26},{"v":0,"x":10,"y":26},{"v":0,"x":11,"y":26},{"v":0,"x":12,"y":26},{"v":0,"x":13,"y":26},{"v":0,"x":14,"y":26},{"v":0,"x":15,"y":26},{"v":0,"x":16,"y":26},{"v":0,"x":17,"y":26},{"v":0,"x":18,"y":26},{"v":0,"x":19,"y":26},{"v":0,"x":20,"y":26},{"v":0,"x":21,"y":26},{"v":0,"x":22,"y":26},{"v":0,"x":23,"y":26},{"v":0,"x":24,"y":26},{"v":0,"x":25,"y":26},{"v":0,"x":26,"y":26},{"v":0,"x":27,"y":26},{"v":0,"x":0,"y":27},{"v":0,"x":1,"y":27},{"v":0,"x":2,"y":27},{"v":0,"x":3,"y":27},{"v":0,"x":4,"y":27},{"v":0,"x":5,"y":27},{"v":0,"x":6,"y":27},{"v":0,"x":7,"y":27},{"v":0,"x":8,"y":27},{"v":0,"x":9,"y":27},{"v":0,"x":10,"y":27},{"v":0,"x":11,"y":27},{"v":0,"x":12,"y":27},{"v":0,"x":13,"y":27},{"v":0,"x":14,"y":27},{"v":0,"x":15,"y":27},{"v":0,"x":16,"y":27},{"v":0,"x":17,"y":27},{"v":0,"x":18,"y":27},{"v":0,"x":19,"y":27},{"v":0,"x":20,"y":27},{"v":0,"x":21,"y":27},{"v":0,"x":22,"y":27},{"v":0,"x":23,"y":27},{"v":0,"x":24,"y":27},{"v":0,"x":25,"y":27},{"v":0,"x":26,"y":27},{"v":0,"x":27,"y":27}]},"encoding":{"color":{"field":"v","legend":null,"scale":{"reverse":true,"scheme":"greys"},"type":"quantitative"},"x":{"axis":null,"field":"x","type":"ordinal"},"y":{"axis":null,"field":"y","type":"ordinal"}},"height":60,"mark":"rect","width":60},{"data":{"values":[{"v":0,"x":0,"y":0},{"v":0,"x":1,"y":0},{"v":0,"x":2,"y":0},{"v":0,"x":3,"y":0},{"v":0,"x":4,"y":0},{"v":0,"x":5,"y":0},{"v":0,"x":6,"y":0},{"v":0,"x":7,"y":0},{"v":0,"x":8,"y":0},{"v":0,"x":9,"y":0},{"v":0,"x":10,"y":0},{"v":0,"x":11,"y":0},{"v":0,"x":12,"y":0},{"v":0,"x":13,"y":0},{"v":0,"x":14,"y":0},{"v":0,"x":15,"y":0},{"v":0,"x":16,"y":0},{"v":0,"x":17,"y":0},{"v":0,"x":18,"y":0},{"v":0,"x":19,"y":0},{"v":0,"x":20,"y":0},{"v":0,"x":21,"y":0},{"v":0,"x":22,"y":0},{"v":0,"x":23,"y":0},{"v":0,"x":24,"y":0},{"v":0,"x":25,"y":0},{"v":0,"x":26,"y":0},{"v":0,"x":27,"y":0},{"v":0,"x":0,"y":1},{"v":0,"x":1,"y":1},{"v":0,"x":2,"y":1},{"v":0,"x":3,"y":1},{"v":0,"x":4,"y":1},{"v":0,"x":5,"y":1},{"v":0,"x":6,"y":1},{"v":0,"x":7,"y":1},{"v":0,"x":8,"y":1},{"v":0,"x":9,"y":1},{"v":0,"x":10,"y":1},{"v":0,"x":11,"y":1},{"v":0,"x":12,"y":1},{"v":0,"x":13,"y":1},{"v":0,"x":14,"y":1},{"v":0,"x":15,"y":1},{"v":0,"x":16,"y":1},{"v":0,"x":17,"y":1},{"v":0,"x":18,"y":1},{"v":0,"x":19,"y":1},{"v":0,"x":20,"y":1},{"v":0,"x":21,"y":1},{"v":0,"x":22,"y":1},{"v":0,"x":23,"y":1},{"v":0,"x":24,"y":1},{"v":0,"x":25,"y":1},{"v":0,"x":26,"y":1},{"v":0,"x":27,"y":1},{"v":0,"x":0,"y":2},{"v":0,"x":1,"y":2},{"v":0,"x":2,"y":2},{"v":0,"x":3,"y":2},{"v":0,"x":4,"y":2},{"v":0,"x":5,"y":2},{"v":0,"x":6,"y":2},{"v":0,"x":7,"y":2},{"v":0,"x":8,"y":2},{"v":0,"x":9,"y":2},{"v":0,"x":10,"y":2},{"v":0,"x":11,"y":2},{"v":0,"x":12,"y":2},{"v":0,"x":13,"y":2},{"v":0,"x":14,"y":2},{"v":0,"x":15,"y":2},{"v":0,"x":16,"y":2},{"v":0,"x":17,"y":2},{"v":0,"x":18,"y":2},{"v":0,"x":19,"y":2},{"v":0,"x":20,"y":2},{"v":0,"x":21,"y":2},{"v":0,"x":22,"y":2},{"v":0,"x":23,"y":2},{"v":0,"x":24,"y":2},{"v":0,"x":25,"y":2},{"v":0,"x":26,"y":2},{"v":0,"x":27,"y":2},{"v":0,"x":0,"y":3},{"v":0,"x":1,"y":3},{"v":0,"x":2,"y":3},{"v":0,"x":3,"y":3},{"v":0,"x":4,"y":3},{"v":0,"x":5,"y":3},{"v":0,"x":6,"y":3},{"v":0,"x":7,"y":3},{"v":0,"x":8,"y":3},{"v":0,"x":9,"y":3},{"v":0,"x":10,"y":3},{"v":0,"x":11,"y":3},{"v":0,"x":12,"y":3},{"v":0,"x":13,"y":3},{"v":0,"x":14,"y":3},{"v":0,"x":15,"y":3},{"v":0,"x":16,"y":3},{"v":0,"x":17,"y":3},{"v":0,"x":18,"y":3},{"v":0,"x":19,"y":3},{"v":0,"x":20,"y":3},{"v":0,"x":21,"y":3},{"v":0,"x":22,"y":3},{"v":0,"x":23,"y":3},{"v":0,"x":24,"y":3},{"v":0,"x":25,"y":3},{"v":0,"x":26,"y":3},{"v":0,"x":27,"y":3},{"v":0,"x":0,"y":4},{"v":0,"x":1,"y":4},{"v":0,"x":2,"y":4},{"v":0,"x":3,"y":4},{"v":0,"x":4,"y":4},{"v":0,"x":5,"y":4},{"v":0,"x":6,"y":4},{"v":0,"x":7,"y":4},{"v":0,"x":8,"y":4},{"v":0,"x":9,"y":4},{"v":0,"x":10,"y":4},{"v":0,"x":11,"y":4},{"v":145,"x":12,"y":4},{"v":255,"x":13,"y":4},{"v":211,"x":14,"y":4},{"v":31,"x":15,"y":4},{"v":0,"x":16,"y":4},{"v":0,"x":17,"y":4},{"v":0,"x":18,"y":4},{"v":0,"x":19,"y":4},{"v":0,"x":20,"y":4},{"v":0,"x":21,"y":4},{"v":0,"x":22,"y":4},{"v":0,"x":23,"y":4},{"v":0,"x":24,"y":4},{"v":0,"x":25,"y":4},{"v":0,"x":26,"y":4},{"v":0,"x":27,"y":4},{"v":0,"x":0,"y":5},{"v":0,"x":1,"y":5},{"v":0,"x":2,"y":5},{"v":0,"x":3,"y":5},{"v":0,"x":4,"y":5},{"v":0,"x":5,"y":5},{"v":0,"x":6,"y":5},{"v":0,"x":7,"y":5},{"v":0,"x":8,"y":5},{"v":0,"x":9,"y":5},{"v":0,"x":10,"y":5},{"v":32,"x":11,"y":5},{"v":237,"x":12,"y":5},{"v":253,"x":13,"y":5},{"v":252,"x":14,"y":5},{"v":71,"x":15,"y":5},{"v":0,"x":16,"y":5},{"v":0,"x":17,"y":5},{"v":0,"x":18,"y":5},{"v":0,"x":19,"y":5},{"v":0,"x":20,"y":5},{"v":0,"x":21,"y":5},{"v":0,"x":22,"y":5},{"v":0,"x":23,"y":5},{"v":0,"x":24,"y":5},{"v":0,"x":25,"y":5},{"v":0,"x":26,"y":5},{"v":0,"x":27,"y":5},{"v":0,"x":0,"y":6},{"v":0,"x":1,"y":6},{"v":0,"x":2,"y":6},{"v":0,"x":3,"y":6},{"v":0,"x":4,"y":6},{"v":0,"x":5,"y":6},{"v":0,"x":6,"y":6},{"v":0,"x":7,"y":6},{"v":0,"x":8,"y":6},{"v":0,"x":9,"y":6},{"v":0,"x":10,"y":6},{"v":11,"x":11,"y":6},{"v":175,"x":12,"y":6},{"v":253,"x":13,"y":6},{"v":252,"x":14,"y":6},{"v":71,"x":15,"y":6},{"v":0,"x":16,"y":6},{"v":0,"x":17,"y":6},{"v":0,"x":18,"y":6},{"v":0,"x":19,"y":6},{"v":0,"x":20,"y":6},{"v":0,"x":21,"y":6},{"v":0,"x":22,"y":6},{"v":0,"x":23,"y":6},{"v":0,"x":24,"y":6},{"v":0,"x":25,"y":6},{"v":0,"x":26,"y":6},{"v":0,"x":27,"y":6},{"v":0,"x":0,"y":7},{"v":0,"x":1,"y":7},{"v":0,"x":2,"y":7},{"v":0,"x":3,"y":7},{"v":0,"x":4,"y":7},{"v":0,"x":5,"y":7},{"v":0,"x":6,"y":7},{"v":0,"x":7,"y":7},{"v":0,"x":8,"y":7},{"v":0,"x":9,"y":7},{"v":0,"x":10,"y":7},{"v":0,"x":11,"y":7},{"v":144,"x":12,"y":7},{"v":253,"x":13,"y":7},{"v":252,"x":14,"y":7},{"v":71,"x":15,"y":7},{"v":0,"x":16,"y":7},{"v":0,"x":17,"y":7},{"v":0,"x":18,"y":7},{"v":0,"x":19,"y":7},{"v":0,"x":20,"y":7},{"v":0,"x":21,"y":7},{"v":0,"x":22,"y":7},{"v":0,"x":23,"y":7},{"v":0,"x":24,"y":7},{"v":0,"x":25,"y":7},{"v":0,"x":26,"y":7},{"v":0,"x":27,"y":7},{"v":0,"x":0,"y":8},{"v":0,"x":1,"y":8},{"v":0,"x":2,"y":8},{"v":0,"x":3,"y":8},{"v":0,"x":4,"y":8},{"v":0,"x":5,"y":8},{"v":0,"x":6,"y":8},{"v":0,"x":7,"y":8},{"v":0,"x":8,"y":8},{"v":0,"x":9,"y":8},{"v":0,"x":10,"y":8},{"v":16,"x":11,"y":8},{"v":191,"x":12,"y":8},{"v":253,"x":13,"y":8},{"v":252,"x":14,"y":8},{"v":71,"x":15,"y":8},{"v":0,"x":16,"y":8},{"v":0,"x":17,"y":8},{"v":0,"x":18,"y":8},{"v":0,"x":19,"y":8},{"v":0,"x":20,"y":8},{"v":0,"x":21,"y":8},{"v":0,"x":22,"y":8},{"v":0,"x":23,"y":8},{"v":0,"x":24,"y":8},{"v":0,"x":25,"y":8},{"v":0,"x":26,"y":8},{"v":0,"x":27,"y":8},{"v":0,"x":0,"y":9},{"v":0,"x":1,"y":9},{"v":0,"x":2,"y":9},{"v":0,"x":3,"y":9},{"v":0,"x":4,"y":9},{"v":0,"x":5,"y":9},{"v":0,"x":6,"y":9},{"v":0,"x":7,"y":9},{"v":0,"x":8,"y":9},{"v":0,"x":9,"y":9},{"v":0,"x":10,"y":9},{"v":26,"x":11,"y":9},{"v":221,"x":12,"y":9},{"v":253,"x":13,"y":9},{"v":252,"x":14,"y":9},{"v":124,"x":15,"y":9},{"v":31,"x":16,"y":9},{"v":0,"x":17,"y":9},{"v":0,"x":18,"y":9},{"v":0,"x":19,"y":9},{"v":0,"x":20,"y":9},{"v":0,"x":21,"y":9},{"v":0,"x":22,"y":9},{"v":0,"x":23,"y":9},{"v":0,"x":24,"y":9},{"v":0,"x":25,"y":9},{"v":0,"x":26,"y":9},{"v":0,"x":27,"y":9},{"v":0,"x":0,"y":10},{"v":0,"x":1,"y":10},{"v":0,"x":2,"y":10},{"v":0,"x":3,"y":10},{"v":0,"x":4,"y":10},{"v":0,"x":5,"y":10},{"v":0,"x":6,"y":10},{"v":0,"x":7,"y":10},{"v":0,"x":8,"y":10},{"v":0,"x":9,"y":10},{"v":0,"x":10,"y":10},{"v":0,"x":11,"y":10},{"v":125,"x":12,"y":10},{"v":253,"x":13,"y":10},{"v":252,"x":14,"y":10},{"v":252,"x":15,"y":10},{"v":108,"x":16,"y":10},{"v":0,"x":17,"y":10},{"v":0,"x":18,"y":10},{"v":0,"x":19,"y":10},{"v":0,"x":20,"y":10},{"v":0,"x":21,"y":10},{"v":0,"x":22,"y":10},{"v":0,"x":23,"y":10},{"v":0,"x":24,"y":10},{"v":0,"x":25,"y":10},{"v":0,"x":26,"y":10},{"v":0,"x":27,"y":10},{"v":0,"x":0,"y":11},{"v":0,"x":1,"y":11},{"v":0,"x":2,"y":11},{"v":0,"x":3,"y":11},{"v":0,"x":4,"y":11},{"v":0,"x":5,"y":11},{"v":0,"x":6,"y":11},{"v":0,"x":7,"y":11},{"v":0,"x":8,"y":11},{"v":0,"x":9,"y":11},{"v":0,"x":10,"y":11},{"v":0,"x":11,"y":11},{"v":0,"x":12,"y":11},{"v":253,"x":13,"y":11},{"v":252,"x":14,"y":11},{"v":252,"x":15,"y":11},{"v":108,"x":16,"y":11},{"v":0,"x":17,"y":11},{"v":0,"x":18,"y":11},{"v":0,"x":19,"y":11},{"v":0,"x":20,"y":11},{"v":0,"x":21,"y":11},{"v":0,"x":22,"y":11},{"v":0,"x":23,"y":11},{"v":0,"x":24,"y":11},{"v":0,"x":25,"y":11},{"v":0,"x":26,"y":11},{"v":0,"x":27,"y":11},{"v":0,"x":0,"y":12},{"v":0,"x":1,"y":12},{"v":0,"x":2,"y":12},{"v":0,"x":3,"y":12},{"v":0,"x":4,"y":12},{"v":0,"x":5,"y":12},{"v":0,"x":6,"y":12},{"v":0,"x":7,"y":12},{"v":0,"x":8,"y":12},{"v":0,"x":9,"y":12},{"v":0,"x":10,"y":12},{"v":0,"x":11,"y":12},{"v":0,"x":12,"y":12},{"v":255,"x":13,"y":12},{"v":253,"x":14,"y":12},{"v":253,"x":15,"y":12},{"v":108,"x":16,"y":12},{"v":0,"x":17,"y":12},{"v":0,"x":18,"y":12},{"v":0,"x":19,"y":12},{"v":0,"x":20,"y":12},{"v":0,"x":21,"y":12},{"v":0,"x":22,"y":12},{"v":0,"x":23,"y":12},{"v":0,"x":24,"y":12},{"v":0,"x":25,"y":12},{"v":0,"x":26,"y":12},{"v":0,"x":27,"y":12},{"v":0,"x":0,"y":13},{"v":0,"x":1,"y":13},{"v":0,"x":2,"y":13},{"v":0,"x":3,"y":13},{"v":0,"x":4,"y":13},{"v":0,"x":5,"y":13},{"v":0,"x":6,"y":13},{"v":0,"x":7,"y":13},{"v":0,"x":8,"y":13},{"v":0,"x":9,"y":13},{"v":0,"x":10,"y":13},{"v":0,"x":11,"y":13},{"v":0,"x":12,"y":13},{"v":253,"x":13,"y":13},{"v":252,"x":14,"y":13},{"v":252,"x":15,"y":13},{"v":108,"x":16,"y":13},{"v":0,"x":17,"y":13},{"v":0,"x":18,"y":13},{"v":0,"x":19,"y":13},{"v":0,"x":20,"y":13},{"v":0,"x":21,"y":13},{"v":0,"x":22,"y":13},{"v":0,"x":23,"y":13},{"v":0,"x":24,"y":13},{"v":0,"x":25,"y":13},{"v":0,"x":26,"y":13},{"v":0,"x":27,"y":13},{"v":0,"x":0,"y":14},{"v":0,"x":1,"y":14},{"v":0,"x":2,"y":14},{"v":0,"x":3,"y":14},{"v":0,"x":4,"y":14},{"v":0,"x":5,"y":14},{"v":0,"x":6,"y":14},{"v":0,"x":7,"y":14},{"v":0,"x":8,"y":14},{"v":0,"x":9,"y":14},{"v":0,"x":10,"y":14},{"v":0,"x":11,"y":14},{"v":0,"x":12,"y":14},{"v":253,"x":13,"y":14},{"v":252,"x":14,"y":14},{"v":252,"x":15,"y":14},{"v":108,"x":16,"y":14},{"v":0,"x":17,"y":14},{"v":0,"x":18,"y":14},{"v":0,"x":19,"y":14},{"v":0,"x":20,"y":14},{"v":0,"x":21,"y":14},{"v":0,"x":22,"y":14},{"v":0,"x":23,"y":14},{"v":0,"x":24,"y":14},{"v":0,"x":25,"y":14},{"v":0,"x":26,"y":14},{"v":0,"x":27,"y":14},{"v":0,"x":0,"y":15},{"v":0,"x":1,"y":15},{"v":0,"x":2,"y":15},{"v":0,"x":3,"y":15},{"v":0,"x":4,"y":15},{"v":0,"x":5,"y":15},{"v":0,"x":6,"y":15},{"v":0,"x":7,"y":15},{"v":0,"x":8,"y":15},{"v":0,"x":9,"y":15},{"v":0,"x":10,"y":15},{"v":0,"x":11,"y":15},{"v":0,"x":12,"y":15},{"v":253,"x":13,"y":15},{"v":252,"x":14,"y":15},{"v":252,"x":15,"y":15},{"v":108,"x":16,"y":15},{"v":0,"x":17,"y":15},{"v":0,"x":18,"y":15},{"v":0,"x":19,"y":15},{"v":0,"x":20,"y":15},{"v":0,"x":21,"y":15},{"v":0,"x":22,"y":15},{"v":0,"x":23,"y":15},{"v":0,"x":24,"y":15},{"v":0,"x":25,"y":15},{"v":0,"x":26,"y":15},{"v":0,"x":27,"y":15},{"v":0,"x":0,"y":16},{"v":0,"x":1,"y":16},{"v":0,"x":2,"y":16},{"v":0,"x":3,"y":16},{"v":0,"x":4,"y":16},{"v":0,"x":5,"y":16},{"v":0,"x":6,"y":16},{"v":0,"x":7,"y":16},{"v":0,"x":8,"y":16},{"v":0,"x":9,"y":16},{"v":0,"x":10,"y":16},{"v":0,"x":11,"y":16},{"v":0,"x":12,"y":16},{"v":255,"x":13,"y":16},{"v":253,"x":14,"y":16},{"v":253,"x":15,"y":16},{"v":170,"x":16,"y":16},{"v":0,"x":17,"y":16},{"v":0,"x":18,"y":16},{"v":0,"x":19,"y":16},{"v":0,"x":20,"y":16},{"v":0,"x":21,"y":16},{"v":0,"x":22,"y":16},{"v":0,"x":23,"y":16},{"v":0,"x":24,"y":16},{"v":0,"x":25,"y":16},{"v":0,"x":26,"y":16},{"v":0,"x":27,"y":16},{"v":0,"x":0,"y":17},{"v":0,"x":1,"y":17},{"v":0,"x":2,"y":17},{"v":0,"x":3,"y":17},{"v":0,"x":4,"y":17},{"v":0,"x":5,"y":17},{"v":0,"x":6,"y":17},{"v":0,"x":7,"y":17},{"v":0,"x":8,"y":17},{"v":0,"x":9,"y":17},{"v":0,"x":10,"y":17},{"v":0,"x":11,"y":17},{"v":0,"x":12,"y":17},{"v":253,"x":13,"y":17},{"v":252,"x":14,"y":17},{"v":252,"x":15,"y":17},{"v":252,"x":16,"y":17},{"v":42,"x":17,"y":17},{"v":0,"x":18,"y":17},{"v":0,"x":19,"y":17},{"v":0,"x":20,"y":17},{"v":0,"x":21,"y":17},{"v":0,"x":22,"y":17},{"v":0,"x":23,"y":17},{"v":0,"x":24,"y":17},{"v":0,"x":25,"y":17},{"v":0,"x":26,"y":17},{"v":0,"x":27,"y":17},{"v":0,"x":0,"y":18},{"v":0,"x":1,"y":18},{"v":0,"x":2,"y":18},{"v":0,"x":3,"y":18},{"v":0,"x":4,"y":18},{"v":0,"x":5,"y":18},{"v":0,"x":6,"y":18},{"v":0,"x":7,"y":18},{"v":0,"x":8,"y":18},{"v":0,"x":9,"y":18},{"v":0,"x":10,"y":18},{"v":0,"x":11,"y":18},{"v":0,"x":12,"y":18},{"v":149,"x":13,"y":18},{"v":252,"x":14,"y":18},{"v":252,"x":15,"y":18},{"v":252,"x":16,"y":18},{"v":144,"x":17,"y":18},{"v":0,"x":18,"y":18},{"v":0,"x":19,"y":18},{"v":0,"x":20,"y":18},{"v":0,"x":21,"y":18},{"v":0,"x":22,"y":18},{"v":0,"x":23,"y":18},{"v":0,"x":24,"y":18},{"v":0,"x":25,"y":18},{"v":0,"x":26,"y":18},{"v":0,"x":27,"y":18},{"v":0,"x":0,"y":19},{"v":0,"x":1,"y":19},{"v":0,"x":2,"y":19},{"v":0,"x":3,"y":19},{"v":0,"x":4,"y":19},{"v":0,"x":5,"y":19},{"v":0,"x":6,"y":19},{"v":0,"x":7,"y":19},{"v":0,"x":8,"y":19},{"v":0,"x":9,"y":19},{"v":0,"x":10,"y":19},{"v":0,"x":11,"y":19},{"v":0,"x":12,"y":19},{"v":109,"x":13,"y":19},{"v":252,"x":14,"y":19},{"v":252,"x":15,"y":19},{"v":252,"x":16,"y":19},{"v":144,"x":17,"y":19},{"v":0,"x":18,"y":19},{"v":0,"x":19,"y":19},{"v":0,"x":20,"y":19},{"v":0,"x":21,"y":19},{"v":0,"x":22,"y":19},{"v":0,"x":23,"y":19},{"v":0,"x":24,"y":19},{"v":0,"x":25,"y":19},{"v":0,"x":26,"y":19},{"v":0,"x":27,"y":19},{"v":0,"x":0,"y":20},{"v":0,"x":1,"y":20},{"v":0,"x":2,"y":20},{"v":0,"x":3,"y":20},{"v":0,"x":4,"y":20},{"v":0,"x":5,"y":20},{"v":0,"x":6,"y":20},{"v":0,"x":7,"y":20},{"v":0,"x":8,"y":20},{"v":0,"x":9,"y":20},{"v":0,"x":10,"y":20},{"v":0,"x":11,"y":20},{"v":0,"x":12,"y":20},{"v":0,"x":13,"y":20},{"v":218,"x":14,"y":20},{"v":253,"x":15,"y":20},{"v":253,"x":16,"y":20},{"v":255,"x":17,"y":20},{"v":35,"x":18,"y":20},{"v":0,"x":19,"y":20},{"v":0,"x":20,"y":20},{"v":0,"x":21,"y":20},{"v":0,"x":22,"y":20},{"v":0,"x":23,"y":20},{"v":0,"x":24,"y":20},{"v":0,"x":25,"y":20},{"v":0,"x":26,"y":20},{"v":0,"x":27,"y":20},{"v":0,"x":0,"y":21},{"v":0,"x":1,"y":21},{"v":0,"x":2,"y":21},{"v":0,"x":3,"y":21},{"v":0,"x":4,"y":21},{"v":0,"x":5,"y":21},{"v":0,"x":6,"y":21},{"v":0,"x":7,"y":21},{"v":0,"x":8,"y":21},{"v":0,"x":9,"y":21},{"v":0,"x":10,"y":21},{"v":0,"x":11,"y":21},{"v":0,"x":12,"y":21},{"v":0,"x":13,"y":21},{"v":175,"x":14,"y":21},{"v":252,"x":15,"y":21},{"v":252,"x":16,"y":21},{"v":253,"x":17,"y":21},{"v":35,"x":18,"y":21},{"v":0,"x":19,"y":21},{"v":0,"x":20,"y":21},{"v":0,"x":21,"y":21},{"v":0,"x":22,"y":21},{"v":0,"x":23,"y":21},{"v":0,"x":24,"y":21},{"v":0,"x":25,"y":21},{"v":0,"x":26,"y":21},{"v":0,"x":27,"y":21},{"v":0,"x":0,"y":22},{"v":0,"x":1,"y":22},{"v":0,"x":2,"y":22},{"v":0,"x":3,"y":22},{"v":0,"x":4,"y":22},{"v":0,"x":5,"y":22},{"v":0,"x":6,"y":22},{"v":0,"x":7,"y":22},{"v":0,"x":8,"y":22},{"v":0,"x":9,"y":22},{"v":0,"x":10,"y":22},{"v":0,"x":11,"y":22},{"v":0,"x":12,"y":22},{"v":0,"x":13,"y":22},{"v":73,"x":14,"y":22},{"v":252,"x":15,"y":22},{"v":252,"x":16,"y":22},{"v":253,"x":17,"y":22},{"v":35,"x":18,"y":22},{"v":0,"x":19,"y":22},{"v":0,"x":20,"y":22},{"v":0,"x":21,"y":22},{"v":0,"x":22,"y":22},{"v":0,"x":23,"y":22},{"v":0,"x":24,"y":22},{"v":0,"x":25,"y":22},{"v":0,"x":26,"y":22},{"v":0,"x":27,"y":22},{"v":0,"x":0,"y":23},{"v":0,"x":1,"y":23},{"v":0,"x":2,"y":23},{"v":0,"x":3,"y":23},{"v":0,"x":4,"y":23},{"v":0,"x":5,"y":23},{"v":0,"x":6,"y":23},{"v":0,"x":7,"y":23},{"v":0,"x":8,"y":23},{"v":0,"x":9,"y":23},{"v":0,"x":10,"y":23},{"v":0,"x":11,"y":23},{"v":0,"x":12,"y":23},{"v":0,"x":13,"y":23},{"v":31,"x":14,"y":23},{"v":211,"x":15,"y":23},{"v":252,"x":16,"y":23},{"v":253,"x":17,"y":23},{"v":35,"x":18,"y":23},{"v":0,"x":19,"y":23},{"v":0,"x":20,"y":23},{"v":0,"x":21,"y":23},{"v":0,"x":22,"y":23},{"v":0,"x":23,"y":23},{"v":0,"x":24,"y":23},{"v":0,"x":25,"y":23},{"v":0,"x":26,"y":23},{"v":0,"x":27,"y":23},{"v":0,"x":0,"y":24},{"v":0,"x":1,"y":24},{"v":0,"x":2,"y":24},{"v":0,"x":3,"y":24},{"v":0,"x":4,"y":24},{"v":0,"x":5,"y":24},{"v":0,"x":6,"y":24},{"v":0,"x":7,"y":24},{"v":0,"x":8,"y":24},{"v":0,"x":9,"y":24},{"v":0,"x":10,"y":24},{"v":0,"x":11,"y":24},{"v":0,"x":12,"y":24},{"v":0,"x":13,"y":24},{"v":0,"x":14,"y":24},{"v":0,"x":15,"y":24},{"v":0,"x":16,"y":24},{"v":0,"x":17,"y":24},{"v":0,"x":18,"y":24},{"v":0,"x":19,"y":24},{"v":0,"x":20,"y":24},{"v":0,"x":21,"y":24},{"v":0,"x":22,"y":24},{"v":0,"x":23,"y":24},{"v":0,"x":24,"y":24},{"v":0,"x":25,"y":24},{"v":0,"x":26,"y":24},{"v":0,"x":27,"y":24},{"v":0,"x":0,"y":25},{"v":0,"x":1,"y":25},{"v":0,"x":2,"y":25},{"v":0,"x":3,"y":25},{"v":0,"x":4,"y":25},{"v":0,"x":5,"y":25},{"v":0,"x":6,"y":25},{"v":0,"x":7,"y":25},{"v":0,"x":8,"y":25},{"v":0,"x":9,"y":25},{"v":0,"x":10,"y":25},{"v":0,"x":11,"y":25},{"v":0,"x":12,"y":25},{"v":0,"x":13,"y":25},{"v":0,"x":14,"y":25},{"v":0,"x":15,"y":25},{"v":0,"x":16,"y":25},{"v":0,"x":17,"y":25},{"v":0,"x":18,"y":25},{"v":0,"x":19,"y":25},{"v":0,"x":20,"y":25},{"v":0,"x":21,"y":25},{"v":0,"x":22,"y":25},{"v":0,"x":23,"y":25},{"v":0,"x":24,"y":25},{"v":0,"x":25,"y":25},{"v":0,"x":26,"y":25},{"v":0,"x":27,"y":25},{"v":0,"x":0,"y":26},{"v":0,"x":1,"y":26},{"v":0,"x":2,"y":26},{"v":0,"x":3,"y":26},{"v":0,"x":4,"y":26},{"v":0,"x":5,"y":26},{"v":0,"x":6,"y":26},{"v":0,"x":7,"y":26},{"v":0,"x":8,"y":26},{"v":0,"x":9,"y":26},{"v":0,"x":10,"y":26},{"v":0,"x":11,"y":26},{"v":0,"x":12,"y":26},{"v":0,"x":13,"y":26},{"v":0,"x":14,"y":26},{"v":0,"x":15,"y":26},{"v":0,"x":16,"y":26},{"v":0,"x":17,"y":26},{"v":0,"x":18,"y":26},{"v":0,"x":19,"y":26},{"v":0,"x":20,"y":26},{"v":0,"x":21,"y":26},{"v":0,"x":22,"y":26},{"v":0,"x":23,"y":26},{"v":0,"x":24,"y":26},{"v":0,"x":25,"y":26},{"v":0,"x":26,"y":26},{"v":0,"x":27,"y":26},{"v":0,"x":0,"y":27},{"v":0,"x":1,"y":27},{"v":0,"x":2,"y":27},{"v":0,"x":3,"y":27},{"v":0,"x":4,"y":27},{"v":0,"x":5,"y":27},{"v":0,"x":6,"y":27},{"v":0,"x":7,"y":27},{"v":0,"x":8,"y":27},{"v":0,"x":9,"y":27},{"v":0,"x":10,"y":27},{"v":0,"x":11,"y":27},{"v":0,"x":12,"y":27},{"v":0,"x":13,"y":27},{"v":0,"x":14,"y":27},{"v":0,"x":15,"y":27},{"v":0,"x":16,"y":27},{"v":0,"x":17,"y":27},{"v":0,"x":18,"y":27},{"v":0,"x":19,"y":27},{"v":0,"x":20,"y":27},{"v":0,"x":21,"y":27},{"v":0,"x":22,"y":27},{"v":0,"x":23,"y":27},{"v":0,"x":24,"y":27},{"v":0,"x":25,"y":27},{"v":0,"x":26,"y":27},{"v":0,"x":27,"y":27}]},"encoding":{"color":{"field":"v","legend":null,"scale":{"reverse":true,"scheme":"greys"},"type":"quantitative"},"x":{"axis":null,"field":"x","type":"ordinal"},"y":{"axis":null,"field":"y","type":"ordinal"}},"height":60,"mark":"rect","width":60},{"data":{"values":[{"v":0,"x":0,"y":0},{"v":0,"x":1,"y":0},{"v":0,"x":2,"y":0},{"v":0,"x":3,"y":0},{"v":0,"x":4,"y":0},{"v":0,"x":5,"y":0},{"v":0,"x":6,"y":0},{"v":0,"x":7,"y":0},{"v":0,"x":8,"y":0},{"v":0,"x":9,"y":0},{"v":0,"x":10,"y":0},{"v":0,"x":11,"y":0},{"v":0,"x":12,"y":0},{"v":0,"x":13,"y":0},{"v":0,"x":14,"y":0},{"v":0,"x":15,"y":0},{"v":0,"x":16,"y":0},{"v":0,"x":17,"y":0},{"v":0,"x":18,"y":0},{"v":0,"x":19,"y":0},{"v":0,"x":20,"y":0},{"v":0,"x":21,"y":0},{"v":0,"x":22,"y":0},{"v":0,"x":23,"y":0},{"v":0,"x":24,"y":0},{"v":0,"x":25,"y":0},{"v":0,"x":26,"y":0},{"v":0,"x":27,"y":0},{"v":0,"x":0,"y":1},{"v":0,"x":1,"y":1},{"v":0,"x":2,"y":1},{"v":0,"x":3,"y":1},{"v":0,"x":4,"y":1},{"v":0,"x":5,"y":1},{"v":0,"x":6,"y":1},{"v":0,"x":7,"y":1},{"v":0,"x":8,"y":1},{"v":0,"x":9,"y":1},{"v":0,"x":10,"y":1},{"v":0,"x":11,"y":1},{"v":0,"x":12,"y":1},{"v":0,"x":13,"y":1},{"v":0,"x":14,"y":1},{"v":0,"x":15,"y":1},{"v":0,"x":16,"y":1},{"v":0,"x":17,"y":1},{"v":0,"x":18,"y":1},{"v":0,"x":19,"y":1},{"v":0,"x":20,"y":1},{"v":0,"x":21,"y":1},{"v":0,"x":22,"y":1},{"v":0,"x":23,"y":1},{"v":0,"x":24,"y":1},{"v":0,"x":25,"y":1},{"v":0,"x":26,"y":1},{"v":0,"x":27,"y":1},{"v":0,"x":0,"y":2},{"v":0,"x":1,"y":2},{"v":0,"x":2,"y":2},{"v":0,"x":3,"y":2},{"v":0,"x":4,"y":2},{"v":0,"x":5,"y":2},{"v":0,"x":6,"y":2},{"v":0,"x":7,"y":2},{"v":0,"x":8,"y":2},{"v":0,"x":9,"y":2},{"v":0,"x":10,"y":2},{"v":0,"x":11,"y":2},{"v":0,"x":12,"y":2},{"v":0,"x":13,"y":2},{"v":0,"x":14,"y":2},{"v":0,"x":15,"y":2},{"v":0,"x":16,"y":2},{"v":0,"x":17,"y":2},{"v":0,"x":18,"y":2},{"v":0,"x":19,"y":2},{"v":0,"x":20,"y":2},{"v":0,"x":21,"y":2},{"v":0,"x":22,"y":2},{"v":0,"x":23,"y":2},{"v":0,"x":24,"y":2},{"v":0,"x":25,"y":2},{"v":0,"x":26,"y":2},{"v":0,"x":27,"y":2},{"v":0,"x":0,"y":3},{"v":0,"x":1,"y":3},{"v":0,"x":2,"y":3},{"v":0,"x":3,"y":3},{"v":0,"x":4,"y":3},{"v":0,"x":5,"y":3},{"v":0,"x":6,"y":3},{"v":0,"x":7,"y":3},{"v":0,"x":8,"y":3},{"v":0,"x":9,"y":3},{"v":0,"x":10,"y":3},{"v":0,"x":11,"y":3},{"v":0,"x":12,"y":3},{"v":0,"x":13,"y":3},{"v":0,"x":14,"y":3},{"v":0,"x":15,"y":3},{"v":0,"x":16,"y":3},{"v":0,"x":17,"y":3},{"v":0,"x":18,"y":3},{"v":0,"x":19,"y":3},{"v":0,"x":20,"y":3},{"v":0,"x":21,"y":3},{"v":0,"x":22,"y":3},{"v":0,"x":23,"y":3},{"v":0,"x":24,"y":3},{"v":0,"x":25,"y":3},{"v":0,"x":26,"y":3},{"v":0,"x":27,"y":3},{"v":0,"x":0,"y":4},{"v":0,"x":1,"y":4},{"v":0,"x":2,"y":4},{"v":0,"x":3,"y":4},{"v":0,"x":4,"y":4},{"v":0,"x":5,"y":4},{"v":0,"x":6,"y":4},{"v":0,"x":7,"y":4},{"v":0,"x":8,"y":4},{"v":0,"x":9,"y":4},{"v":0,"x":10,"y":4},{"v":0,"x":11,"y":4},{"v":0,"x":12,"y":4},{"v":0,"x":13,"y":4},{"v":0,"x":14,"y":4},{"v":0,"x":15,"y":4},{"v":0,"x":16,"y":4},{"v":0,"x":17,"y":4},{"v":0,"x":18,"y":4},{"v":0,"x":19,"y":4},{"v":0,"x":20,"y":4},{"v":0,"x":21,"y":4},{"v":0,"x":22,"y":4},{"v":0,"x":23,"y":4},{"v":0,"x":24,"y":4},{"v":0,"x":25,"y":4},{"v":0,"x":26,"y":4},{"v":0,"x":27,"y":4},{"v":0,"x":0,"y":5},{"v":0,"x":1,"y":5},{"v":0,"x":2,"y":5},{"v":0,"x":3,"y":5},{"v":0,"x":4,"y":5},{"v":0,"x":5,"y":5},{"v":0,"x":6,"y":5},{"v":0,"x":7,"y":5},{"v":0,"x":8,"y":5},{"v":0,"x":9,"y":5},{"v":0,"x":10,"y":5},{"v":38,"x":11,"y":5},{"v":43,"x":12,"y":5},{"v":105,"x":13,"y":5},{"v":255,"x":14,"y":5},{"v":253,"x":15,"y":5},{"v":253,"x":16,"y":5},{"v":253,"x":17,"y":5},{"v":253,"x":18,"y":5},{"v":253,"x":19,"y":5},{"v":174,"x":20,"y":5},{"v":6,"x":21,"y":5},{"v":0,"x":22,"y":5},{"v":0,"x":23,"y":5},{"v":0,"x":24,"y":5},{"v":0,"x":25,"y":5},{"v":0,"x":26,"y":5},{"v":0,"x":27,"y":5},{"v":0,"x":0,"y":6},{"v":0,"x":1,"y":6},{"v":0,"x":2,"y":6},{"v":0,"x":3,"y":6},{"v":0,"x":4,"y":6},{"v":0,"x":5,"y":6},{"v":0,"x":6,"y":6},{"v":0,"x":7,"y":6},{"v":0,"x":8,"y":6},{"v":43,"x":9,"y":6},{"v":139,"x":10,"y":6},{"v":224,"x":11,"y":6},{"v":226,"x":12,"y":6},{"v":252,"x":13,"y":6},{"v":253,"x":14,"y":6},{"v":252,"x":15,"y":6},{"v":252,"x":16,"y":6},{"v":252,"x":17,"y":6},{"v":252,"x":18,"y":6},{"v":252,"x":19,"y":6},{"v":252,"x":20,"y":6},{"v":158,"x":21,"y":6},{"v":14,"x":22,"y":6},{"v":0,"x":23,"y":6},{"v":0,"x":24,"y":6},{"v":0,"x":25,"y":6},{"v":0,"x":26,"y":6},{"v":0,"x":27,"y":6},{"v":0,"x":0,"y":7},{"v":0,"x":1,"y":7},{"v":0,"x":2,"y":7},{"v":0,"x":3,"y":7},{"v":0,"x":4,"y":7},{"v":0,"x":5,"y":7},{"v":0,"x":6,"y":7},{"v":0,"x":7,"y":7},{"v":0,"x":8,"y":7},{"v":178,"x":9,"y":7},{"v":252,"x":10,"y":7},{"v":252,"x":11,"y":7},{"v":252,"x":12,"y":7},{"v":252,"x":13,"y":7},{"v":253,"x":14,"y":7},{"v":252,"x":15,"y":7},{"v":252,"x":16,"y":7},{"v":252,"x":17,"y":7},{"v":252,"x":18,"y":7},{"v":252,"x":19,"y":7},{"v":252,"x":20,"y":7},{"v":252,"x":21,"y":7},{"v":59,"x":22,"y":7},{"v":0,"x":23,"y":7},{"v":0,"x":24,"y":7},{"v":0,"x":25,"y":7},{"v":0,"x":26,"y":7},{"v":0,"x":27,"y":7},{"v":0,"x":0,"y":8},{"v":0,"x":1,"y":8},{"v":0,"x":2,"y":8},{"v":0,"x":3,"y":8},{"v":0,"x":4,"y":8},{"v":0,"x":5,"y":8},{"v":0,"x":6,"y":8},{"v":0,"x":7,"y":8},{"v":0,"x":8,"y":8},{"v":109,"x":9,"y":8},{"v":252,"x":10,"y":8},{"v":252,"x":11,"y":8},{"v":230,"x":12,"y":8},{"v":132,"x":13,"y":8},{"v":133,"x":14,"y":8},{"v":132,"x":15,"y":8},{"v":132,"x":16,"y":8},{"v":189,"x":17,"y":8},{"v":252,"x":18,"y":8},{"v":252,"x":19,"y":8},{"v":252,"x":20,"y":8},{"v":252,"x":21,"y":8},{"v":59,"x":22,"y":8},{"v":0,"x":23,"y":8},{"v":0,"x":24,"y":8},{"v":0,"x":25,"y":8},{"v":0,"x":26,"y":8},{"v":0,"x":27,"y":8},{"v":0,"x":0,"y":9},{"v":0,"x":1,"y":9},{"v":0,"x":2,"y":9},{"v":0,"x":3,"y":9},{"v":0,"x":4,"y":9},{"v":0,"x":5,"y":9},{"v":0,"x":6,"y":9},{"v":0,"x":7,"y":9},{"v":0,"x":8,"y":9},{"v":4,"x":9,"y":9},{"v":29,"x":10,"y":9},{"v":29,"x":11,"y":9},{"v":24,"x":12,"y":9},{"v":0,"x":13,"y":9},{"v":0,"x":14,"y":9},{"v":0,"x":15,"y":9},{"v":0,"x":16,"y":9},{"v":14,"x":17,"y":9},{"v":226,"x":18,"y":9},{"v":252,"x":19,"y":9},{"v":252,"x":20,"y":9},{"v":172,"x":21,"y":9},{"v":7,"x":22,"y":9},{"v":0,"x":23,"y":9},{"v":0,"x":24,"y":9},{"v":0,"x":25,"y":9},{"v":0,"x":26,"y":9},{"v":0,"x":27,"y":9},{"v":0,"x":0,"y":10},{"v":0,"x":1,"y":10},{"v":0,"x":2,"y":10},{"v":0,"x":3,"y":10},{"v":0,"x":4,"y":10},{"v":0,"x":5,"y":10},{"v":0,"x":6,"y":10},{"v":0,"x":7,"y":10},{"v":0,"x":8,"y":10},{"v":0,"x":9,"y":10},{"v":0,"x":10,"y":10},{"v":0,"x":11,"y":10},{"v":0,"x":12,"y":10},{"v":0,"x":13,"y":10},{"v":0,"x":14,"y":10},{"v":0,"x":15,"y":10},{"v":0,"x":16,"y":10},{"v":85,"x":17,"y":10},{"v":243,"x":18,"y":10},{"v":252,"x":19,"y":10},{"v":252,"x":20,"y":10},{"v":144,"x":21,"y":10},{"v":0,"x":22,"y":10},{"v":0,"x":23,"y":10},{"v":0,"x":24,"y":10},{"v":0,"x":25,"y":10},{"v":0,"x":26,"y":10},{"v":0,"x":27,"y":10},{"v":0,"x":0,"y":11},{"v":0,"x":1,"y":11},{"v":0,"x":2,"y":11},{"v":0,"x":3,"y":11},{"v":0,"x":4,"y":11},{"v":0,"x":5,"y":11},{"v":0,"x":6,"y":11},{"v":0,"x":7,"y":11},{"v":0,"x":8,"y":11},{"v":0,"x":9,"y":11},{"v":0,"x":10,"y":11},{"v":0,"x":11,"y":11},{"v":0,"x":12,"y":11},{"v":0,"x":13,"y":11},{"v":0,"x":14,"y":11},{"v":0,"x":15,"y":11},{"v":88,"x":16,"y":11},{"v":189,"x":17,"y":11},{"v":252,"x":18,"y":11},{"v":252,"x":19,"y":11},{"v":252,"x":20,"y":11},{"v":14,"x":21,"y":11},{"v":0,"x":22,"y":11},{"v":0,"x":23,"y":11},{"v":0,"x":24,"y":11},{"v":0,"x":25,"y":11},{"v":0,"x":26,"y":11},{"v":0,"x":27,"y":11},{"v":0,"x":0,"y":12},{"v":0,"x":1,"y":12},{"v":0,"x":2,"y":12},{"v":0,"x":3,"y":12},{"v":0,"x":4,"y":12},{"v":0,"x":5,"y":12},{"v":0,"x":6,"y":12},{"v":0,"x":7,"y":12},{"v":0,"x":8,"y":12},{"v":0,"x":9,"y":12},{"v":0,"x":10,"y":12},{"v":0,"x":11,"y":12},{"v":0,"x":12,"y":12},{"v":0,"x":13,"y":12},{"v":91,"x":14,"y":12},{"v":212,"x":15,"y":12},{"v":247,"x":16,"y":12},{"v":252,"x":17,"y":12},{"v":252,"x":18,"y":12},{"v":252,"x":19,"y":12},{"v":204,"x":20,"y":12},{"v":9,"x":21,"y":12},{"v":0,"x":22,"y":12},{"v":0,"x":23,"y":12},{"v":0,"x":24,"y":12},{"v":0,"x":25,"y":12},{"v":0,"x":26,"y":12},{"v":0,"x":27,"y":12},{"v":0,"x":0,"y":13},{"v":0,"x":1,"y":13},{"v":0,"x":2,"y":13},{"v":0,"x":3,"y":13},{"v":0,"x":4,"y":13},{"v":0,"x":5,"y":13},{"v":0,"x":6,"y":13},{"v":0,"x":7,"y":13},{"v":0,"x":8,"y":13},{"v":32,"x":9,"y":13},{"v":125,"x":10,"y":13},{"v":193,"x":11,"y":13},{"v":193,"x":12,"y":13},{"v":193,"x":13,"y":13},{"v":253,"x":14,"y":13},{"v":252,"x":15,"y":13},{"v":252,"x":16,"y":13},{"v":252,"x":17,"y":13},{"v":238,"x":18,"y":13},{"v":102,"x":19,"y":13},{"v":28,"x":20,"y":13},{"v":0,"x":21,"y":13},{"v":0,"x":22,"y":13},{"v":0,"x":23,"y":13},{"v":0,"x":24,"y":13},{"v":0,"x":25,"y":13},{"v":0,"x":26,"y":13},{"v":0,"x":27,"y":13},{"v":0,"x":0,"y":14},{"v":0,"x":1,"y":14},{"v":0,"x":2,"y":14},{"v":0,"x":3,"y":14},{"v":0,"x":4,"y":14},{"v":0,"x":5,"y":14},{"v":0,"x":6,"y":14},{"v":0,"x":7,"y":14},{"v":45,"x":8,"y":14},{"v":222,"x":9,"y":14},{"v":252,"x":10,"y":14},{"v":252,"x":11,"y":14},{"v":252,"x":12,"y":14},{"v":252,"x":13,"y":14},{"v":253,"x":14,"y":14},{"v":252,"x":15,"y":14},{"v":252,"x":16,"y":14},{"v":252,"x":17,"y":14},{"v":177,"x":18,"y":14},{"v":0,"x":19,"y":14},{"v":0,"x":20,"y":14},{"v":0,"x":21,"y":14},{"v":0,"x":22,"y":14},{"v":0,"x":23,"y":14},{"v":0,"x":24,"y":14},{"v":0,"x":25,"y":14},{"v":0,"x":26,"y":14},{"v":0,"x":27,"y":14},{"v":0,"x":0,"y":15},{"v":0,"x":1,"y":15},{"v":0,"x":2,"y":15},{"v":0,"x":3,"y":15},{"v":0,"x":4,"y":15},{"v":0,"x":5,"y":15},{"v":0,"x":6,"y":15},{"v":0,"x":7,"y":15},{"v":45,"x":8,"y":15},{"v":223,"x":9,"y":15},{"v":253,"x":10,"y":15},{"v":253,"x":11,"y":15},{"v":253,"x":12,"y":15},{"v":253,"x":13,"y":15},{"v":255,"x":14,"y":15},{"v":253,"x":15,"y":15},{"v":253,"x":16,"y":15},{"v":253,"x":17,"y":15},{"v":253,"x":18,"y":15},{"v":74,"x":19,"y":15},{"v":0,"x":20,"y":15},{"v":0,"x":21,"y":15},{"v":0,"x":22,"y":15},{"v":0,"x":23,"y":15},{"v":0,"x":24,"y":15},{"v":0,"x":25,"y":15},{"v":0,"x":26,"y":15},{"v":0,"x":27,"y":15},{"v":0,"x":0,"y":16},{"v":0,"x":1,"y":16},{"v":0,"x":2,"y":16},{"v":0,"x":3,"y":16},{"v":0,"x":4,"y":16},{"v":0,"x":5,"y":16},{"v":0,"x":6,"y":16},{"v":0,"x":7,"y":16},{"v":0,"x":8,"y":16},{"v":31,"x":9,"y":16},{"v":123,"x":10,"y":16},{"v":52,"x":11,"y":16},{"v":44,"x":12,"y":16},{"v":44,"x":13,"y":16},{"v":44,"x":14,"y":16},{"v":44,"x":15,"y":16},{"v":143,"x":16,"y":16},{"v":252,"x":17,"y":16},{"v":252,"x":18,"y":16},{"v":74,"x":19,"y":16},{"v":0,"x":20,"y":16},{"v":0,"x":21,"y":16},{"v":0,"x":22,"y":16},{"v":0,"x":23,"y":16},{"v":0,"x":24,"y":16},{"v":0,"x":25,"y":16},{"v":0,"x":26,"y":16},{"v":0,"x":27,"y":16},{"v":0,"x":0,"y":17},{"v":0,"x":1,"y":17},{"v":0,"x":2,"y":17},{"v":0,"x":3,"y":17},{"v":0,"x":4,"y":17},{"v":0,"x":5,"y":17},{"v":0,"x":6,"y":17},{"v":0,"x":7,"y":17},{"v":0,"x":8,"y":17},{"v":0,"x":9,"y":17},{"v":0,"x":10,"y":17},{"v":0,"x":11,"y":17},{"v":0,"x":12,"y":17},{"v":0,"x":13,"y":17},{"v":0,"x":14,"y":17},{"v":0,"x":15,"y":17},{"v":15,"x":16,"y":17},{"v":252,"x":17,"y":17},{"v":252,"x":18,"y":17},{"v":74,"x":19,"y":17},{"v":0,"x":20,"y":17},{"v":0,"x":21,"y":17},{"v":0,"x":22,"y":17},{"v":0,"x":23,"y":17},{"v":0,"x":24,"y":17},{"v":0,"x":25,"y":17},{"v":0,"x":26,"y":17},{"v":0,"x":27,"y":17},{"v":0,"x":0,"y":18},{"v":0,"x":1,"y":18},{"v":0,"x":2,"y":18},{"v":0,"x":3,"y":18},{"v":0,"x":4,"y":18},{"v":0,"x":5,"y":18},{"v":0,"x":6,"y":18},{"v":0,"x":7,"y":18},{"v":0,"x":8,"y":18},{"v":0,"x":9,"y":18},{"v":0,"x":10,"y":18},{"v":0,"x":11,"y":18},{"v":0,"x":12,"y":18},{"v":0,"x":13,"y":18},{"v":0,"x":14,"y":18},{"v":0,"x":15,"y":18},{"v":86,"x":16,"y":18},{"v":252,"x":17,"y":18},{"v":252,"x":18,"y":18},{"v":74,"x":19,"y":18},{"v":0,"x":20,"y":18},{"v":0,"x":21,"y":18},{"v":0,"x":22,"y":18},{"v":0,"x":23,"y":18},{"v":0,"x":24,"y":18},{"v":0,"x":25,"y":18},{"v":0,"x":26,"y":18},{"v":0,"x":27,"y":18},{"v":0,"x":0,"y":19},{"v":0,"x":1,"y":19},{"v":0,"x":2,"y":19},{"v":0,"x":3,"y":19},{"v":0,"x":4,"y":19},{"v":0,"x":5,"y":19},{"v":5,"x":6,"y":19},{"v":75,"x":7,"y":19},{"v":9,"x":8,"y":19},{"v":0,"x":9,"y":19},{"v":0,"x":10,"y":19},{"v":0,"x":11,"y":19},{"v":0,"x":12,"y":19},{"v":0,"x":13,"y":19},{"v":0,"x":14,"y":19},{"v":98,"x":15,"y":19},{"v":242,"x":16,"y":19},{"v":252,"x":17,"y":19},{"v":252,"x":18,"y":19},{"v":74,"x":19,"y":19},{"v":0,"x":20,"y":19},{"v":0,"x":21,"y":19},{"v":0,"x":22,"y":19},{"v":0,"x":23,"y":19},{"v":0,"x":24,"y":19},{"v":0,"x":25,"y":19},{"v":0,"x":26,"y":19},{"v":0,"x":27,"y":19},{"v":0,"x":0,"y":20},{"v":0,"x":1,"y":20},{"v":0,"x":2,"y":20},{"v":0,"x":3,"y":20},{"v":0,"x":4,"y":20},{"v":61,"x":5,"y":20},{"v":183,"x":6,"y":20},{"v":252,"x":7,"y":20},{"v":29,"x":8,"y":20},{"v":0,"x":9,"y":20},{"v":0,"x":10,"y":20},{"v":0,"x":11,"y":20},{"v":0,"x":12,"y":20},{"v":18,"x":13,"y":20},{"v":92,"x":14,"y":20},{"v":239,"x":15,"y":20},{"v":252,"x":16,"y":20},{"v":252,"x":17,"y":20},{"v":243,"x":18,"y":20},{"v":65,"x":19,"y":20},{"v":0,"x":20,"y":20},{"v":0,"x":21,"y":20},{"v":0,"x":22,"y":20},{"v":0,"x":23,"y":20},{"v":0,"x":24,"y":20},{"v":0,"x":25,"y":20},{"v":0,"x":26,"y":20},{"v":0,"x":27,"y":20},{"v":0,"x":0,"y":21},{"v":0,"x":1,"y":21},{"v":0,"x":2,"y":21},{"v":0,"x":3,"y":21},{"v":0,"x":4,"y":21},{"v":208,"x":5,"y":21},{"v":252,"x":6,"y":21},{"v":252,"x":7,"y":21},{"v":147,"x":8,"y":21},{"v":134,"x":9,"y":21},{"v":134,"x":10,"y":21},{"v":134,"x":11,"y":21},{"v":134,"x":12,"y":21},{"v":203,"x":13,"y":21},{"v":253,"x":14,"y":21},{"v":252,"x":15,"y":21},{"v":252,"x":16,"y":21},{"v":188,"x":17,"y":21},{"v":83,"x":18,"y":21},{"v":0,"x":19,"y":21},{"v":0,"x":20,"y":21},{"v":0,"x":21,"y":21},{"v":0,"x":22,"y":21},{"v":0,"x":23,"y":21},{"v":0,"x":24,"y":21},{"v":0,"x":25,"y":21},{"v":0,"x":26,"y":21},{"v":0,"x":27,"y":21},{"v":0,"x":0,"y":22},{"v":0,"x":1,"y":22},{"v":0,"x":2,"y":22},{"v":0,"x":3,"y":22},{"v":0,"x":4,"y":22},{"v":208,"x":5,"y":22},{"v":252,"x":6,"y":22},{"v":252,"x":7,"y":22},{"v":252,"x":8,"y":22},{"v":252,"x":9,"y":22},{"v":252,"x":10,"y":22},{"v":252,"x":11,"y":22},{"v":252,"x":12,"y":22},{"v":252,"x":13,"y":22},{"v":253,"x":14,"y":22},{"v":230,"x":15,"y":22},{"v":153,"x":16,"y":22},{"v":8,"x":17,"y":22},{"v":0,"x":18,"y":22},{"v":0,"x":19,"y":22},{"v":0,"x":20,"y":22},{"v":0,"x":21,"y":22},{"v":0,"x":22,"y":22},{"v":0,"x":23,"y":22},{"v":0,"x":24,"y":22},{"v":0,"x":25,"y":22},{"v":0,"x":26,"y":22},{"v":0,"x":27,"y":22},{"v":0,"x":0,"y":23},{"v":0,"x":1,"y":23},{"v":0,"x":2,"y":23},{"v":0,"x":3,"y":23},{"v":0,"x":4,"y":23},{"v":49,"x":5,"y":23},{"v":157,"x":6,"y":23},{"v":252,"x":7,"y":23},{"v":252,"x":8,"y":23},{"v":252,"x":9,"y":23},{"v":252,"x":10,"y":23},{"v":252,"x":11,"y":23},{"v":217,"x":12,"y":23},{"v":207,"x":13,"y":23},{"v":146,"x":14,"y":23},{"v":45,"x":15,"y":23},{"v":0,"x":16,"y":23},{"v":0,"x":17,"y":23},{"v":0,"x":18,"y":23},{"v":0,"x":19,"y":23},{"v":0,"x":20,"y":23},{"v":0,"x":21,"y":23},{"v":0,"x":22,"y":23},{"v":0,"x":23,"y":23},{"v":0,"x":24,"y":23},{"v":0,"x":25,"y":23},{"v":0,"x":26,"y":23},{"v":0,"x":27,"y":23},{"v":0,"x":0,"y":24},{"v":0,"x":1,"y":24},{"v":0,"x":2,"y":24},{"v":0,"x":3,"y":24},{"v":0,"x":4,"y":24},{"v":0,"x":5,"y":24},{"v":7,"x":6,"y":24},{"v":103,"x":7,"y":24},{"v":235,"x":8,"y":24},{"v":252,"x":9,"y":24},{"v":172,"x":10,"y":24},{"v":103,"x":11,"y":24},{"v":24,"x":12,"y":24},{"v":0,"x":13,"y":24},{"v":0,"x":14,"y":24},{"v":0,"x":15,"y":24},{"v":0,"x":16,"y":24},{"v":0,"x":17,"y":24},{"v":0,"x":18,"y":24},{"v":0,"x":19,"y":24},{"v":0,"x":20,"y":24},{"v":0,"x":21,"y":24},{"v":0,"x":22,"y":24},{"v":0,"x":23,"y":24},{"v":0,"x":24,"y":24},{"v":0,"x":25,"y":24},{"v":0,"x":26,"y":24},{"v":0,"x":27,"y":24},{"v":0,"x":0,"y":25},{"v":0,"x":1,"y":25},{"v":0,"x":2,"y":25},{"v":0,"x":3,"y":25},{"v":0,"x":4,"y":25},{"v":0,"x":5,"y":25},{"v":0,"x":6,"y":25},{"v":0,"x":7,"y":25},{"v":0,"x":8,"y":25},{"v":0,"x":9,"y":25},{"v":0,"x":10,"y":25},{"v":0,"x":11,"y":25},{"v":0,"x":12,"y":25},{"v":0,"x":13,"y":25},{"v":0,"x":14,"y":25},{"v":0,"x":15,"y":25},{"v":0,"x":16,"y":25},{"v":0,"x":17,"y":25},{"v":0,"x":18,"y":25},{"v":0,"x":19,"y":25},{"v":0,"x":20,"y":25},{"v":0,"x":21,"y":25},{"v":0,"x":22,"y":25},{"v":0,"x":23,"y":25},{"v":0,"x":24,"y":25},{"v":0,"x":25,"y":25},{"v":0,"x":26,"y":25},{"v":0,"x":27,"y":25},{"v":0,"x":0,"y":26},{"v":0,"x":1,"y":26},{"v":0,"x":2,"y":26},{"v":0,"x":3,"y":26},{"v":0,"x":4,"y":26},{"v":0,"x":5,"y":26},{"v":0,"x":6,"y":26},{"v":0,"x":7,"y":26},{"v":0,"x":8,"y":26},{"v":0,"x":9,"y":26},{"v":0,"x":10,"y":26},{"v":0,"x":11,"y":26},{"v":0,"x":12,"y":26},{"v":0,"x":13,"y":26},{"v":0,"x":14,"y":26},{"v":0,"x":15,"y":26},{"v":0,"x":16,"y":26},{"v":0,"x":17,"y":26},{"v":0,"x":18,"y":26},{"v":0,"x":19,"y":26},{"v":0,"x":20,"y":26},{"v":0,"x":21,"y":26},{"v":0,"x":22,"y":26},{"v":0,"x":23,"y":26},{"v":0,"x":24,"y":26},{"v":0,"x":25,"y":26},{"v":0,"x":26,"y":26},{"v":0,"x":27,"y":26},{"v":0,"x":0,"y":27},{"v":0,"x":1,"y":27},{"v":0,"x":2,"y":27},{"v":0,"x":3,"y":27},{"v":0,"x":4,"y":27},{"v":0,"x":5,"y":27},{"v":0,"x":6,"y":27},{"v":0,"x":7,"y":27},{"v":0,"x":8,"y":27},{"v":0,"x":9,"y":27},{"v":0,"x":10,"y":27},{"v":0,"x":11,"y":27},{"v":0,"x":12,"y":27},{"v":0,"x":13,"y":27},{"v":0,"x":14,"y":27},{"v":0,"x":15,"y":27},{"v":0,"x":16,"y":27},{"v":0,"x":17,"y":27},{"v":0,"x":18,"y":27},{"v":0,"x":19,"y":27},{"v":0,"x":20,"y":27},{"v":0,"x":21,"y":27},{"v":0,"x":22,"y":27},{"v":0,"x":23,"y":27},{"v":0,"x":24,"y":27},{"v":0,"x":25,"y":27},{"v":0,"x":26,"y":27},{"v":0,"x":27,"y":27}]},"encoding":{"color":{"field":"v","legend":null,"scale":{"reverse":true,"scheme":"greys"},"type":"quantitative"},"x":{"axis":null,"field":"x","type":"ordinal"},"y":{"axis":null,"field":"y","type":"ordinal"}},"height":60,"mark":"rect","width":60},{"data":{"values":[{"v":0,"x":0,"y":0},{"v":0,"x":1,"y":0},{"v":0,"x":2,"y":0},{"v":0,"x":3,"y":0},{"v":0,"x":4,"y":0},{"v":0,"x":5,"y":0},{"v":0,"x":6,"y":0},{"v":0,"x":7,"y":0},{"v":0,"x":8,"y":0},{"v":0,"x":9,"y":0},{"v":0,"x":10,"y":0},{"v":0,"x":11,"y":0},{"v":0,"x":12,"y":0},{"v":0,"x":13,"y":0},{"v":0,"x":14,"y":0},{"v":0,"x":15,"y":0},{"v":0,"x":16,"y":0},{"v":0,"x":17,"y":0},{"v":0,"x":18,"y":0},{"v":0,"x":19,"y":0},{"v":0,"x":20,"y":0},{"v":0,"x":21,"y":0},{"v":0,"x":22,"y":0},{"v":0,"x":23,"y":0},{"v":0,"x":24,"y":0},{"v":0,"x":25,"y":0},{"v":0,"x":26,"y":0},{"v":0,"x":27,"y":0},{"v":0,"x":0,"y":1},{"v":0,"x":1,"y":1},{"v":0,"x":2,"y":1},{"v":0,"x":3,"y":1},{"v":0,"x":4,"y":1},{"v":0,"x":5,"y":1},{"v":0,"x":6,"y":1},{"v":0,"x":7,"y":1},{"v":0,"x":8,"y":1},{"v":0,"x":9,"y":1},{"v":0,"x":10,"y":1},{"v":0,"x":11,"y":1},{"v":0,"x":12,"y":1},{"v":0,"x":13,"y":1},{"v":0,"x":14,"y":1},{"v":0,"x":15,"y":1},{"v":0,"x":16,"y":1},{"v":0,"x":17,"y":1},{"v":0,"x":18,"y":1},{"v":0,"x":19,"y":1},{"v":0,"x":20,"y":1},{"v":0,"x":21,"y":1},{"v":0,"x":22,"y":1},{"v":0,"x":23,"y":1},{"v":0,"x":24,"y":1},{"v":0,"x":25,"y":1},{"v":0,"x":26,"y":1},{"v":0,"x":27,"y":1},{"v":0,"x":0,"y":2},{"v":0,"x":1,"y":2},{"v":0,"x":2,"y":2},{"v":0,"x":3,"y":2},{"v":0,"x":4,"y":2},{"v":0,"x":5,"y":2},{"v":0,"x":6,"y":2},{"v":0,"x":7,"y":2},{"v":0,"x":8,"y":2},{"v":0,"x":9,"y":2},{"v":0,"x":10,"y":2},{"v":0,"x":11,"y":2},{"v":0,"x":12,"y":2},{"v":0,"x":13,"y":2},{"v":0,"x":14,"y":2},{"v":0,"x":15,"y":2},{"v":0,"x":16,"y":2},{"v":0,"x":17,"y":2},{"v":0,"x":18,"y":2},{"v":0,"x":19,"y":2},{"v":0,"x":20,"y":2},{"v":0,"x":21,"y":2},{"v":0,"x":22,"y":2},{"v":0,"x":23,"y":2},{"v":0,"x":24,"y":2},{"v":0,"x":25,"y":2},{"v":0,"x":26,"y":2},{"v":0,"x":27,"y":2},{"v":0,"x":0,"y":3},{"v":0,"x":1,"y":3},{"v":0,"x":2,"y":3},{"v":0,"x":3,"y":3},{"v":0,"x":4,"y":3},{"v":0,"x":5,"y":3},{"v":0,"x":6,"y":3},{"v":0,"x":7,"y":3},{"v":0,"x":8,"y":3},{"v":0,"x":9,"y":3},{"v":0,"x":10,"y":3},{"v":0,"x":11,"y":3},{"v":0,"x":12,"y":3},{"v":0,"x":13,"y":3},{"v":0,"x":14,"y":3},{"v":0,"x":15,"y":3},{"v":0,"x":16,"y":3},{"v":0,"x":17,"y":3},{"v":0,"x":18,"y":3},{"v":0,"x":19,"y":3},{"v":0,"x":20,"y":3},{"v":0,"x":21,"y":3},{"v":0,"x":22,"y":3},{"v":0,"x":23,"y":3},{"v":0,"x":24,"y":3},{"v":0,"x":25,"y":3},{"v":0,"x":26,"y":3},{"v":0,"x":27,"y":3},{"v":0,"x":0,"y":4},{"v":0,"x":1,"y":4},{"v":0,"x":2,"y":4},{"v":0,"x":3,"y":4},{"v":0,"x":4,"y":4},{"v":0,"x":5,"y":4},{"v":0,"x":6,"y":4},{"v":0,"x":7,"y":4},{"v":0,"x":8,"y":4},{"v":0,"x":9,"y":4},{"v":0,"x":10,"y":4},{"v":0,"x":11,"y":4},{"v":0,"x":12,"y":4},{"v":0,"x":13,"y":4},{"v":0,"x":14,"y":4},{"v":0,"x":15,"y":4},{"v":0,"x":16,"y":4},{"v":0,"x":17,"y":4},{"v":0,"x":18,"y":4},{"v":0,"x":19,"y":4},{"v":0,"x":20,"y":4},{"v":0,"x":21,"y":4},{"v":0,"x":22,"y":4},{"v":0,"x":23,"y":4},{"v":0,"x":24,"y":4},{"v":0,"x":25,"y":4},{"v":0,"x":26,"y":4},{"v":0,"x":27,"y":4},{"v":0,"x":0,"y":5},{"v":0,"x":1,"y":5},{"v":0,"x":2,"y":5},{"v":0,"x":3,"y":5},{"v":0,"x":4,"y":5},{"v":0,"x":5,"y":5},{"v":0,"x":6,"y":5},{"v":0,"x":7,"y":5},{"v":0,"x":8,"y":5},{"v":0,"x":9,"y":5},{"v":0,"x":10,"y":5},{"v":0,"x":11,"y":5},{"v":5,"x":12,"y":5},{"v":63,"x":13,"y":5},{"v":197,"x":14,"y":5},{"v":0,"x":15,"y":5},{"v":0,"x":16,"y":5},{"v":0,"x":17,"y":5},{"v":0,"x":18,"y":5},{"v":0,"x":19,"y":5},{"v":0,"x":20,"y":5},{"v":0,"x":21,"y":5},{"v":0,"x":22,"y":5},{"v":0,"x":23,"y":5},{"v":0,"x":24,"y":5},{"v":0,"x":25,"y":5},{"v":0,"x":26,"y":5},{"v":0,"x":27,"y":5},{"v":0,"x":0,"y":6},{"v":0,"x":1,"y":6},{"v":0,"x":2,"y":6},{"v":0,"x":3,"y":6},{"v":0,"x":4,"y":6},{"v":0,"x":5,"y":6},{"v":0,"x":6,"y":6},{"v":0,"x":7,"y":6},{"v":0,"x":8,"y":6},{"v":0,"x":9,"y":6},{"v":0,"x":10,"y":6},{"v":0,"x":11,"y":6},{"v":20,"x":12,"y":6},{"v":254,"x":13,"y":6},{"v":230,"x":14,"y":6},{"v":24,"x":15,"y":6},{"v":0,"x":16,"y":6},{"v":0,"x":17,"y":6},{"v":0,"x":18,"y":6},{"v":0,"x":19,"y":6},{"v":0,"x":20,"y":6},{"v":0,"x":21,"y":6},{"v":0,"x":22,"y":6},{"v":0,"x":23,"y":6},{"v":0,"x":24,"y":6},{"v":0,"x":25,"y":6},{"v":0,"x":26,"y":6},{"v":0,"x":27,"y":6},{"v":0,"x":0,"y":7},{"v":0,"x":1,"y":7},{"v":0,"x":2,"y":7},{"v":0,"x":3,"y":7},{"v":0,"x":4,"y":7},{"v":0,"x":5,"y":7},{"v":0,"x":6,"y":7},{"v":0,"x":7,"y":7},{"v":0,"x":8,"y":7},{"v":0,"x":9,"y":7},{"v":0,"x":10,"y":7},{"v":0,"x":11,"y":7},{"v":20,"x":12,"y":7},{"v":254,"x":13,"y":7},{"v":254,"x":14,"y":7},{"v":48,"x":15,"y":7},{"v":0,"x":16,"y":7},{"v":0,"x":17,"y":7},{"v":0,"x":18,"y":7},{"v":0,"x":19,"y":7},{"v":0,"x":20,"y":7},{"v":0,"x":21,"y":7},{"v":0,"x":22,"y":7},{"v":0,"x":23,"y":7},{"v":0,"x":24,"y":7},{"v":0,"x":25,"y":7},{"v":0,"x":26,"y":7},{"v":0,"x":27,"y":7},{"v":0,"x":0,"y":8},{"v":0,"x":1,"y":8},{"v":0,"x":2,"y":8},{"v":0,"x":3,"y":8},{"v":0,"x":4,"y":8},{"v":0,"x":5,"y":8},{"v":0,"x":6,"y":8},{"v":0,"x":7,"y":8},{"v":0,"x":8,"y":8},{"v":0,"x":9,"y":8},{"v":0,"x":10,"y":8},{"v":0,"x":11,"y":8},{"v":20,"x":12,"y":8},{"v":254,"x":13,"y":8},{"v":255,"x":14,"y":8},{"v":48,"x":15,"y":8},{"v":0,"x":16,"y":8},{"v":0,"x":17,"y":8},{"v":0,"x":18,"y":8},{"v":0,"x":19,"y":8},{"v":0,"x":20,"y":8},{"v":0,"x":21,"y":8},{"v":0,"x":22,"y":8},{"v":0,"x":23,"y":8},{"v":0,"x":24,"y":8},{"v":0,"x":25,"y":8},{"v":0,"x":26,"y":8},{"v":0,"x":27,"y":8},{"v":0,"x":0,"y":9},{"v":0,"x":1,"y":9},{"v":0,"x":2,"y":9},{"v":0,"x":3,"y":9},{"v":0,"x":4,"y":9},{"v":0,"x":5,"y":9},{"v":0,"x":6,"y":9},{"v":0,"x":7,"y":9},{"v":0,"x":8,"y":9},{"v":0,"x":9,"y":9},{"v":0,"x":10,"y":9},{"v":0,"x":11,"y":9},{"v":20,"x":12,"y":9},{"v":254,"x":13,"y":9},{"v":254,"x":14,"y":9},{"v":57,"x":15,"y":9},{"v":0,"x":16,"y":9},{"v":0,"x":17,"y":9},{"v":0,"x":18,"y":9},{"v":0,"x":19,"y":9},{"v":0,"x":20,"y":9},{"v":0,"x":21,"y":9},{"v":0,"x":22,"y":9},{"v":0,"x":23,"y":9},{"v":0,"x":24,"y":9},{"v":0,"x":25,"y":9},{"v":0,"x":26,"y":9},{"v":0,"x":27,"y":9},{"v":0,"x":0,"y":10},{"v":0,"x":1,"y":10},{"v":0,"x":2,"y":10},{"v":0,"x":3,"y":10},{"v":0,"x":4,"y":10},{"v":0,"x":5,"y":10},{"v":0,"x":6,"y":10},{"v":0,"x":7,"y":10},{"v":0,"x":8,"y":10},{"v":0,"x":9,"y":10},{"v":0,"x":10,"y":10},{"v":0,"x":11,"y":10},{"v":20,"x":12,"y":10},{"v":254,"x":13,"y":10},{"v":254,"x":14,"y":10},{"v":108,"x":15,"y":10},{"v":0,"x":16,"y":10},{"v":0,"x":17,"y":10},{"v":0,"x":18,"y":10},{"v":0,"x":19,"y":10},{"v":0,"x":20,"y":10},{"v":0,"x":21,"y":10},{"v":0,"x":22,"y":10},{"v":0,"x":23,"y":10},{"v":0,"x":24,"y":10},{"v":0,"x":25,"y":10},{"v":0,"x":26,"y":10},{"v":0,"x":27,"y":10},{"v":0,"x":0,"y":11},{"v":0,"x":1,"y":11},{"v":0,"x":2,"y":11},{"v":0,"x":3,"y":11},{"v":0,"x":4,"y":11},{"v":0,"x":5,"y":11},{"v":0,"x":6,"y":11},{"v":0,"x":7,"y":11},{"v":0,"x":8,"y":11},{"v":0,"x":9,"y":11},{"v":0,"x":10,"y":11},{"v":0,"x":11,"y":11},{"v":16,"x":12,"y":11},{"v":239,"x":13,"y":11},{"v":254,"x":14,"y":11},{"v":143,"x":15,"y":11},{"v":0,"x":16,"y":11},{"v":0,"x":17,"y":11},{"v":0,"x":18,"y":11},{"v":0,"x":19,"y":11},{"v":0,"x":20,"y":11},{"v":0,"x":21,"y":11},{"v":0,"x":22,"y":11},{"v":0,"x":23,"y":11},{"v":0,"x":24,"y":11},{"v":0,"x":25,"y":11},{"v":0,"x":26,"y":11},{"v":0,"x":27,"y":11},{"v":0,"x":0,"y":12},{"v":0,"x":1,"y":12},{"v":0,"x":2,"y":12},{"v":0,"x":3,"y":12},{"v":0,"x":4,"y":12},{"v":0,"x":5,"y":12},{"v":0,"x":6,"y":12},{"v":0,"x":7,"y":12},{"v":0,"x":8,"y":12},{"v":0,"x":9,"y":12},{"v":0,"x":10,"y":12},{"v":0,"x":11,"y":12},{"v":0,"x":12,"y":12},{"v":178,"x":13,"y":12},{"v":254,"x":14,"y":12},{"v":143,"x":15,"y":12},{"v":0,"x":16,"y":12},{"v":0,"x":17,"y":12},{"v":0,"x":18,"y":12},{"v":0,"x":19,"y":12},{"v":0,"x":20,"y":12},{"v":0,"x":21,"y":12},{"v":0,"x":22,"y":12},{"v":0,"x":23,"y":12},{"v":0,"x":24,"y":12},{"v":0,"x":25,"y":12},{"v":0,"x":26,"y":12},{"v":0,"x":27,"y":12},{"v":0,"x":0,"y":13},{"v":0,"x":1,"y":13},{"v":0,"x":2,"y":13},{"v":0,"x":3,"y":13},{"v":0,"x":4,"y":13},{"v":0,"x":5,"y":13},{"v":0,"x":6,"y":13},{"v":0,"x":7,"y":13},{"v":0,"x":8,"y":13},{"v":0,"x":9,"y":13},{"v":0,"x":10,"y":13},{"v":0,"x":11,"y":13},{"v":0,"x":12,"y":13},{"v":178,"x":13,"y":13},{"v":254,"x":14,"y":13},{"v":143,"x":15,"y":13},{"v":0,"x":16,"y":13},{"v":0,"x":17,"y":13},{"v":0,"x":18,"y":13},{"v":0,"x":19,"y":13},{"v":0,"x":20,"y":13},{"v":0,"x":21,"y":13},{"v":0,"x":22,"y":13},{"v":0,"x":23,"y":13},{"v":0,"x":24,"y":13},{"v":0,"x":25,"y":13},{"v":0,"x":26,"y":13},{"v":0,"x":27,"y":13},{"v":0,"x":0,"y":14},{"v":0,"x":1,"y":14},{"v":0,"x":2,"y":14},{"v":0,"x":3,"y":14},{"v":0,"x":4,"y":14},{"v":0,"x":5,"y":14},{"v":0,"x":6,"y":14},{"v":0,"x":7,"y":14},{"v":0,"x":8,"y":14},{"v":0,"x":9,"y":14},{"v":0,"x":10,"y":14},{"v":0,"x":11,"y":14},{"v":0,"x":12,"y":14},{"v":178,"x":13,"y":14},{"v":254,"x":14,"y":14},{"v":162,"x":15,"y":14},{"v":0,"x":16,"y":14},{"v":0,"x":17,"y":14},{"v":0,"x":18,"y":14},{"v":0,"x":19,"y":14},{"v":0,"x":20,"y":14},{"v":0,"x":21,"y":14},{"v":0,"x":22,"y":14},{"v":0,"x":23,"y":14},{"v":0,"x":24,"y":14},{"v":0,"x":25,"y":14},{"v":0,"x":26,"y":14},{"v":0,"x":27,"y":14},{"v":0,"x":0,"y":15},{"v":0,"x":1,"y":15},{"v":0,"x":2,"y":15},{"v":0,"x":3,"y":15},{"v":0,"x":4,"y":15},{"v":0,"x":5,"y":15},{"v":0,"x":6,"y":15},{"v":0,"x":7,"y":15},{"v":0,"x":8,"y":15},{"v":0,"x":9,"y":15},{"v":0,"x":10,"y":15},{"v":0,"x":11,"y":15},{"v":0,"x":12,"y":15},{"v":178,"x":13,"y":15},{"v":254,"x":14,"y":15},{"v":240,"x":15,"y":15},{"v":0,"x":16,"y":15},{"v":0,"x":17,"y":15},{"v":0,"x":18,"y":15},{"v":0,"x":19,"y":15},{"v":0,"x":20,"y":15},{"v":0,"x":21,"y":15},{"v":0,"x":22,"y":15},{"v":0,"x":23,"y":15},{"v":0,"x":24,"y":15},{"v":0,"x":25,"y":15},{"v":0,"x":26,"y":15},{"v":0,"x":27,"y":15},{"v":0,"x":0,"y":16},{"v":0,"x":1,"y":16},{"v":0,"x":2,"y":16},{"v":0,"x":3,"y":16},{"v":0,"x":4,"y":16},{"v":0,"x":5,"y":16},{"v":0,"x":6,"y":16},{"v":0,"x":7,"y":16},{"v":0,"x":8,"y":16},{"v":0,"x":9,"y":16},{"v":0,"x":10,"y":16},{"v":0,"x":11,"y":16},{"v":0,"x":12,"y":16},{"v":113,"x":13,"y":16},{"v":254,"x":14,"y":16},{"v":240,"x":15,"y":16},{"v":0,"x":16,"y":16},{"v":0,"x":17,"y":16},{"v":0,"x":18,"y":16},{"v":0,"x":19,"y":16},{"v":0,"x":20,"y":16},{"v":0,"x":21,"y":16},{"v":0,"x":22,"y":16},{"v":0,"x":23,"y":16},{"v":0,"x":24,"y":16},{"v":0,"x":25,"y":16},{"v":0,"x":26,"y":16},{"v":0,"x":27,"y":16},{"v":0,"x":0,"y":17},{"v":0,"x":1,"y":17},{"v":0,"x":2,"y":17},{"v":0,"x":3,"y":17},{"v":0,"x":4,"y":17},{"v":0,"x":5,"y":17},{"v":0,"x":6,"y":17},{"v":0,"x":7,"y":17},{"v":0,"x":8,"y":17},{"v":0,"x":9,"y":17},{"v":0,"x":10,"y":17},{"v":0,"x":11,"y":17},{"v":0,"x":12,"y":17},{"v":83,"x":13,"y":17},{"v":254,"x":14,"y":17},{"v":245,"x":15,"y":17},{"v":31,"x":16,"y":17},{"v":0,"x":17,"y":17},{"v":0,"x":18,"y":17},{"v":0,"x":19,"y":17},{"v":0,"x":20,"y":17},{"v":0,"x":21,"y":17},{"v":0,"x":22,"y":17},{"v":0,"x":23,"y":17},{"v":0,"x":24,"y":17},{"v":0,"x":25,"y":17},{"v":0,"x":26,"y":17},{"v":0,"x":27,"y":17},{"v":0,"x":0,"y":18},{"v":0,"x":1,"y":18},{"v":0,"x":2,"y":18},{"v":0,"x":3,"y":18},{"v":0,"x":4,"y":18},{"v":0,"x":5,"y":18},{"v":0,"x":6,"y":18},{"v":0,"x":7,"y":18},{"v":0,"x":8,"y":18},{"v":0,"x":9,"y":18},{"v":0,"x":10,"y":18},{"v":0,"x":11,"y":18},{"v":0,"x":12,"y":18},{"v":79,"x":13,"y":18},{"v":254,"x":14,"y":18},{"v":246,"x":15,"y":18},{"v":38,"x":16,"y":18},{"v":0,"x":17,"y":18},{"v":0,"x":18,"y":18},{"v":0,"x":19,"y":18},{"v":0,"x":20,"y":18},{"v":0,"x":21,"y":18},{"v":0,"x":22,"y":18},{"v":0,"x":23,"y":18},{"v":0,"x":24,"y":18},{"v":0,"x":25,"y":18},{"v":0,"x":26,"y":18},{"v":0,"x":27,"y":18},{"v":0,"x":0,"y":19},{"v":0,"x":1,"y":19},{"v":0,"x":2,"y":19},{"v":0,"x":3,"y":19},{"v":0,"x":4,"y":19},{"v":0,"x":5,"y":19},{"v":0,"x":6,"y":19},{"v":0,"x":7,"y":19},{"v":0,"x":8,"y":19},{"v":0,"x":9,"y":19},{"v":0,"x":10,"y":19},{"v":0,"x":11,"y":19},{"v":0,"x":12,"y":19},{"v":0,"x":13,"y":19},{"v":214,"x":14,"y":19},{"v":254,"x":15,"y":19},{"v":150,"x":16,"y":19},{"v":0,"x":17,"y":19},{"v":0,"x":18,"y":19},{"v":0,"x":19,"y":19},{"v":0,"x":20,"y":19},{"v":0,"x":21,"y":19},{"v":0,"x":22,"y":19},{"v":0,"x":23,"y":19},{"v":0,"x":24,"y":19},{"v":0,"x":25,"y":19},{"v":0,"x":26,"y":19},{"v":0,"x":27,"y":19},{"v":0,"x":0,"y":20},{"v":0,"x":1,"y":20},{"v":0,"x":2,"y":20},{"v":0,"x":3,"y":20},{"v":0,"x":4,"y":20},{"v":0,"x":5,"y":20},{"v":0,"x":6,"y":20},{"v":0,"x":7,"y":20},{"v":0,"x":8,"y":20},{"v":0,"x":9,"y":20},{"v":0,"x":10,"y":20},{"v":0,"x":11,"y":20},{"v":0,"x":12,"y":20},{"v":0,"x":13,"y":20},{"v":144,"x":14,"y":20},{"v":241,"x":15,"y":20},{"v":8,"x":16,"y":20},{"v":0,"x":17,"y":20},{"v":0,"x":18,"y":20},{"v":0,"x":19,"y":20},{"v":0,"x":20,"y":20},{"v":0,"x":21,"y":20},{"v":0,"x":22,"y":20},{"v":0,"x":23,"y":20},{"v":0,"x":24,"y":20},{"v":0,"x":25,"y":20},{"v":0,"x":26,"y":20},{"v":0,"x":27,"y":20},{"v":0,"x":0,"y":21},{"v":0,"x":1,"y":21},{"v":0,"x":2,"y":21},{"v":0,"x":3,"y":21},{"v":0,"x":4,"y":21},{"v":0,"x":5,"y":21},{"v":0,"x":6,"y":21},{"v":0,"x":7,"y":21},{"v":0,"x":8,"y":21},{"v":0,"x":9,"y":21},{"v":0,"x":10,"y":21},{"v":0,"x":11,"y":21},{"v":0,"x":12,"y":21},{"v":0,"x":13,"y":21},{"v":144,"x":14,"y":21},{"v":240,"x":15,"y":21},{"v":2,"x":16,"y":21},{"v":0,"x":17,"y":21},{"v":0,"x":18,"y":21},{"v":0,"x":19,"y":21},{"v":0,"x":20,"y":21},{"v":0,"x":21,"y":21},{"v":0,"x":22,"y":21},{"v":0,"x":23,"y":21},{"v":0,"x":24,"y":21},{"v":0,"x":25,"y":21},{"v":0,"x":26,"y":21},{"v":0,"x":27,"y":21},{"v":0,"x":0,"y":22},{"v":0,"x":1,"y":22},{"v":0,"x":2,"y":22},{"v":0,"x":3,"y":22},{"v":0,"x":4,"y":22},{"v":0,"x":5,"y":22},{"v":0,"x":6,"y":22},{"v":0,"x":7,"y":22},{"v":0,"x":8,"y":22},{"v":0,"x":9,"y":22},{"v":0,"x":10,"y":22},{"v":0,"x":11,"y":22},{"v":0,"x":12,"y":22},{"v":0,"x":13,"y":22},{"v":144,"x":14,"y":22},{"v":254,"x":15,"y":22},{"v":82,"x":16,"y":22},{"v":0,"x":17,"y":22},{"v":0,"x":18,"y":22},{"v":0,"x":19,"y":22},{"v":0,"x":20,"y":22},{"v":0,"x":21,"y":22},{"v":0,"x":22,"y":22},{"v":0,"x":23,"y":22},{"v":0,"x":24,"y":22},{"v":0,"x":25,"y":22},{"v":0,"x":26,"y":22},{"v":0,"x":27,"y":22},{"v":0,"x":0,"y":23},{"v":0,"x":1,"y":23},{"v":0,"x":2,"y":23},{"v":0,"x":3,"y":23},{"v":0,"x":4,"y":23},{"v":0,"x":5,"y":23},{"v":0,"x":6,"y":23},{"v":0,"x":7,"y":23},{"v":0,"x":8,"y"