GithubHelp home page GithubHelp logo

vincent's Introduction

#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.

Status

Version 0.2 is a major release for Vincent, with major syntax changes. All of the Vincent 0.1 features have been ported.

Vincent works with IPython 1.0, including the IPython notebook. Please see Vincent_Examples.ipynb for a demo of all chart types, as well as the new IPython integration API in Vincent 0.2, using the .initialize_notebook() and .display() methods.

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!

vincent's People

Contributors

wrobstory avatar dnmiller avatar lxyu avatar ellisonbg avatar myusuf3 avatar aflaxman avatar minrk avatar pawelmhm avatar tlukasiak avatar maisano avatar wuub avatar julian avatar heinrichfilter avatar metakermit avatar hellerpdx avatar garaud avatar cvrebert avatar ajrenold avatar

Watchers

Ramnath Vaidyanathan avatar James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.