• This repository has been archived on 02/Aug/2019
  • Stars
    star
    2,037
  • Rank 22,710 (Top 0.5 %)
  • Language
    Python
  • License
    MIT License
  • Created over 11 years ago
  • Updated about 8 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A Python to Vega translator

Status

2016-06-18 Update

If you are interested in this library, I would direct you to the Altair project: https://github.com/altair-viz/altair It supports the latest version of vega, is fully-featured, has a great development team, and has been developed with the support of the Vega team at UW.

There will be no more updates, closed issues, or PR merges for the Vincent project. Thanks so much to everyone who tried it or used it along the way.

#Vincent

Travs-CI status

Vincent

###A Python to Vega translator

The folks at Trifacta are making it easy to build visualizations on top of D3 with Vega. Vincent makes it easy to build Vega with Python.

Concept

The data capabilities of Python. The visualization capabilities of JavaScript.

Vincent takes Python data structures and translates them into Vega visualization grammar. It allows for quick iteration of visualization designs via getters and setters on grammar elements, and outputs the final visualization to JSON.

Perhaps most importantly, Vincent groks Pandas DataFrames and Series in an intuitive way.

Installation

$pip install vincent

Warning: requires Pandas, which isn't a simple pip install if you don't already have Numpy installed. If you want to go all-pip, I recommend $pip install numpy then $pip install pandas. Or just use Anaconda.

Docs

Here.

Quickstart

Let's start with some varying data, and then show some different ways to visualize them with Vincent.

Starting with a simple bar chart:

import vincent
bar = vincent.Bar(multi_iter1['y1'])
bar.axis_titles(x='Index', y='Value')
bar.to_json('vega.json')

bars

Plotting a number of lines:

line = vincent.Line(multi_iter1, iter_idx='index')
line.axis_titles(x='Index', y='Value')
line.legend(title='Categories')

lines

Or a real use case, plotting stock data:

line = vincent.Line(price[['GOOG', 'AAPL']])
line.axis_titles(x='Date', y='Price')
line.legend(title='GOOG vs AAPL')

stocks1

Color brewer scales are built-in. For example, plotting a scatter plot with the Set3 colors:

scatter = vincent.Scatter(multi_iter2, iter_idx='index')
scatter.axis_titles(x='Index', y='Data Value')
scatter.legend(title='Categories')
scatter.colors(brew='Set3')

scatter

Area charts:

area = vincent.Area(list_data)

area

Stacked Area Charts from a DataFrame:

stacked = vincent.StackedArea(df_1)
stacked.axis_titles(x='Index', y='Value')
stacked.legend(title='Categories')
stacked.colors(brew='Spectral')

areastack

stacked = vincent.StackedArea(price)
stacked.axis_titles(x='Date', y='Price')
stacked.legend(title='Tech Stocks')

areastack2

Stacked Bar Charts from a DataFrame:

stack = vincent.StackedBar(df_2)
stack.legend(title='Categories')
stack.scales['x'].padding = 0.1

barstack1

stack = vincent.StackedBar(df_farm.T)
stack.axis_titles(x='Total Produce', y='Farms')
stack.legend(title='Produce Types')
stack.colors(brew='Pastel1')

barstack2

Grouped Bars from a DataFrame:

group = vincent.GroupedBar(df_2)
group.legend(title='Categories')
group.colors(brew='Spectral')
group.width=750

groupbar1

group = vincent.GroupedBar(df_farm)
group.axis_titles(x='Total Produce', y='Farms')
group.legend(title='Produce Types')
group.colors(brew='Set2')

groupbar2

Pie charts:

vis = vincent.Pie(farm_1)
vis.legend('Farm 1 Fruit')

pie

Donut charts:

vis = vincent.Pie(farm_1, inner_radius=200)
vis.colors(brew="Set2")
vis.legend('Farm 1 Fruit')

donut

Simple maps can be built quickly (all data can be found in the vincent_map_data repo):

world_topo = r'world-countries.topo.json'
geo_data = [{'name': 'countries',
             'url': world_topo,
             'feature': 'world-countries'}]

vis = vincent.Map(geo_data=geo_data, scale=200)

simplemap

Also with multiple map layers:

geo_data = [{'name': 'counties',
             'url': county_topo,
             'feature': 'us_counties.geo'},
            {'name': 'states',
             'url': state_topo,
             'feature': 'us_states.geo'}]

vis = vincent.Map(geo_data=geo_data, scale=1000, projection='albersUsa')
del vis.marks[1].properties.update
vis.marks[0].properties.update.fill.value = '#084081'
vis.marks[1].properties.enter.stroke.value = '#fff'
vis.marks[0].properties.enter.stroke.value = '#7bccc4'

multiplelayer

Maps can be bound with data to Pandas DataFrames for choropleth visualizations (see here for map data munging):

geo_data = [{'name': 'counties',
             'url': county_topo,
             'feature': 'us_counties.geo'}]

vis = vincent.Map(data=merged, geo_data=geo_data, scale=1100, projection='albersUsa',
          data_bind='Unemployment_rate_2011', data_key='FIPS',
          map_key={'counties': 'properties.FIPS'})
vis.marks[0].properties.enter.stroke_opacity = ValueRef(value=0.5)
vis.to_json('vega.json')

binding1

It can be rebound on the fly with new data and color brewer scales:

vis.rebind(column='Median_Household_Income_2011', brew='YlGnBu')

binding2

For more examples, including how to build these from scratch, see the examples directory, or the docs.

Built from Scratch

To see how the charts are being built with Vincent -> Vega grammar, see the charts.py module.

Building the bar chart from scratch will provide a quick example of building with Vincent:

import pandas as pd
from vincent import (Visualization, Scale, DataRef, Data, PropertySet,
                     Axis, ValueRef, MarkRef, MarkProperties, Mark)

df = pd.DataFrame({'Data 1': [15, 29, 63, 28, 45, 73, 15, 62],
                   'Data 2': [42, 27, 52, 18, 61, 19, 62, 33]})

#Top level Visualization
vis = Visualization(width=500, height=300)
vis.padding = {'top': 10, 'left': 50, 'bottom': 50, 'right': 100}

#Data. We're going to key Data 2 on Data 1
vis.data.append(Data.from_pandas(df, columns=['Data 2'], key_on='Data 1', name='table'))

#Scales
vis.scales.append(Scale(name='x', type='ordinal', range='width',
                        domain=DataRef(data='table', field="data.idx")))
vis.scales.append(Scale(name='y', range='height', nice=True,
                        domain=DataRef(data='table', field="data.val")))

#Axes
vis.axes.extend([Axis(type='x', scale='x'), Axis(type='y', scale='y')])

#Marks
enter_props = PropertySet(x=ValueRef(scale='x', field="data.idx"),
                                     y=ValueRef(scale='y', field="data.val"),
                                     width=ValueRef(scale='x', band=True, offset=-1),
                                     y2=ValueRef(scale='y', value=0))
update_props = PropertySet(fill=ValueRef(value='steelblue'))
mark = Mark(type='rect', from_=MarkRef(data='table'),
            properties=MarkProperties(enter=enter_props,
            update=update_props))

vis.marks.append(mark)
vis.axis_titles(x='Data 1', y='Data 2')
vis.to_json('vega.json')

barscratch

Because the Vega elements are represented by Python classes, it can be difficult to get a good idea of what the Vega grammar looks like:

In [5]: vis.marks[0]
<vincent.marks.Mark at 0x110d630d0>

However, at almost any point in the Vincent stack, you can call the grammar() method to output the Vega grammar as Python data structures:

>>>vis.marks[0].grammar()
{u'from': {u'data': u'table'},
 u'properties': {u'enter': {u'width': {u'band': True,
    u'offset': -1,
    u'scale': u'x'},
   u'x': {u'field': u'data.idx', u'scale': u'x'},
   u'y': {u'field': u'data.val', u'scale': u'y'},
   u'y2': {u'scale': u'y', u'value': 0}},
  u'update': {u'fill': {u'value': u'steelblue'}}},
 u'type': u'rect'}
>>>vis.marks[0].properties.enter.x.grammar()
{u'field': u'data.idx', u'scale': u'x'}

or you can simply output it to a string of JSON:

>>>print(vis.marks[0].to_json())
{
  "type": "rect",
  "from": {
    "data": "table"
  },
  "properties": {
    "update": {
      "fill": {
        "value": "steelblue"
      }
    },
    "enter": {
      "y": {
        "field": "data.val",
        "scale": "y"
      },
      "width": {
        "band": true,
        "scale": "x",
        "offset": -1
      },
      "y2": {
        "scale": "y",
        "value": 0
      },
      "x": {
        "field": "data.idx",
        "scale": "x"
      }
    }
  }
}

Vincent is built around classes and attributes that map 1:1 to Vega grammar, for easy getting, setting, and deleting of grammar elements:

>>>vis.marks[0].properties.enter.grammar()
{u'width': {u'band': True, u'offset': -1, u'scale': u'x'},
 u'x': {u'field': u'data.idx', u'scale': u'x'},
 u'y': {u'field': u'data.val', u'scale': u'y'},
 u'y2': {u'scale': u'y', u'value': 0}}
 >>> del vis.marks[0].properties.enter.width
 >>> vis.marks[0].properties.enter.y2.scale = 'y2'
 >>> vis.marks[0].properties.enter.grammar()
{u'x': {u'field': u'data.idx', u'scale': u'x'},
 u'y': {u'field': u'data.val', u'scale': u'y'},
 u'y2': {u'scale': u'y2', u'value': 0}}

Contributors

Huge thanks to all who have contributed to Vincent development:

  • Rob Story (wrobstory)
  • Dan Miller (dnmiller)
  • Peter Lubell-Doughtie (pld)
  • Lx Yu (lxyu)
  • Damien Garaud (garaud)
  • Abraham Flaxman (aflaxman)
  • Mahdi Yusuf (myusuf3)
  • Richard Maisano (maisano)
  • Julian Berman (Julian)
  • Chris Rebert (cvrebert)
  • Wojciech Bederski (wuub)
  • Min RK (minrk)
  • Drazen Lucanin (kermit666)
  • tlukasiak

Dependencies

  • pandas
  • pkgtools

Testing:

  • mock
  • nose

PSA: you can use pieces of Vincent without Pandas, but its tricky. Besides, Pandas is awesome- try it!

More Repositories

1

bearcart

Creating Rickshaw.js visualizations with Python Pandas
JavaScript
267
star
2

sticky

IPython Notebook + D3
Python
128
star
3

pydataseattle2015

PyData Seattle 2015: Python Data Bikeshed
127
star
4

mcflyin

A small timeseries transformation API built on Flask and Pandas
Python
85
star
5

PythonToScala

A short guide for transitioning from Python to Scala
65
star
6

malort

JSON -> Relational DB Column Types
Python
64
star
7

vincent_map_data

A geodata repository for Vincent examples
63
star
8

pelican_dynamic

Easily embed custom JS and CSS in your Pelican blog articles
Python
52
star
9

climatic

A small toolbox of wind data analysis plotting tools
Python
43
star
10

pdxpython2015

Portland Python Meetup March 2015
41
star
11

pydatasv2014

PyData Silicon Valley 2014 Code + Presentation
CSS
37
star
12

pgshift

Postgres pg_dump -> Redshift
Python
35
star
13

vldb2015

Notes from VLDB conference
30
star
14

d3.chart.choropleth

A d3.chart based choropleth map
JavaScript
26
star
15

redifest

Generate a Redshift .manifest file for a given S3 bucket
Python
21
star
16

pdxdatasci2014

PDX Data Science Meetup November 2014
CSS
12
star
17

DataEngArchSimple

PDX Data Science Meetup March 2016 Presentation
10
star
18

zipwhich

Comparing different zip code datasets
10
star
19

notebook-styles

IPython notebook styles
9
star
20

portlandmapdemo

Creating and Publishing Maps with D3, Dymo, and PhantomJS
JavaScript
7
star
21

reconciler

Reconcile S3 and Redshift
Python
4
star
22

caladan

Tabular Analytics with Clojure
Clojure
4
star
23

ds4ds_2015

Data Structures for Data Science 2015 Slides
3
star
24

yoflask

CSS
2
star
25

tumalo

Clojure Elasticsearch tools
Clojure
2
star
26

wrobstory.github.com

Static blog powered by Pelican
CSS
2
star
27

vegalite-pojo

Generating POJOs from the vega-lite spec
Java
1
star
28

feint

Python
1
star
29

strangeloop_2015

Strangeloop After Strangeloop
1
star