Thursday, March 9, 2017

1st Xap I built

Doing the right thing is more important than doing the thing right

Before implementing the technical details, let me exercise my critical thinking and keep the big picture in mind.
In my understanding, Exaptive Studio is trying to encapsulate and modularize every step of a data pipeline. Basically, the pipeline can be decomposed into 3 steps: data wrangling, data mining, data visualization. But there is no clear cut between these steps because they are closely related. For example, in data mining, we use a lot of statistical learning tools and plotting libraries to extract the useful information, it is like turning over 100 rocks to find 2 interesting nuggets. In data visualization, we only present the few interesting things and deliberately polish them to catch viewers’ eyes. We don’t display the 98% boring things or the dots we fail to connect.
These two purposes of visualization at different stages reveal the exploration-exploitation dilemma, which is a fundamental tradeoff in Reinforcement Learning. This term pops to my mind because I remember the GaTech professors joking at the similar spelling in the Udacity video.
To fully expose the difficulty of implementation in Exaptive, I list the most-common Python codes for data exploration.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
data = pd.read_csv(csvfile)
data.info()
data.head()
data.describe()
data.corr()
data.plot()
data.groupby()
I usually do it in Jupyter notebook because I can get immediate feedback from the result and determine the next direction I want to explore. I can imagine how inefficient it is if we have to pull out the log, build or search for a desirable component. Within Ipython, it is only one line of code!
So the best chance Exaptive Studio can survive and flourish in the data presentation stage, which leverages the power of web-based visualization technologies as such D3.js. There are already strong players like Datameer eating the same market. We have to act very fast to adjust our stratergy to capture more end-users.
Specifically, one of our target markets is data journalism. We should be able to help our users to achieve something like The Facebook IPO, which is data-intensive and highly interactive. In a post-truth era, such reports will stand out and become the new norm. Because false claim is cheap to fabricate but big data is not. Truth and sights that are hidden in the data will eventually prevail. People are so hungry for data-backed news. So don’t let Trump twitter. Let Data Speak. This is huge business!

Building a JavaScript component for data visualization
Steps:
  1. Read relevant documentations and decompose an existing plot component, put it in pure HTML/JavaScript environment and study how it works.
  2. search for the right JavaScript libraries and functions as building blocks. Play with them to understand how they work and put them in a local host. Try Amazon simple storage service to host these visual appealing pages.
  3. Modify these workable JavaScript codes to make them work in Xap.

learn from Exaptive documentation on JavaScript

D3.js in Expative

In studio page, create a new JavaScript Component. Rename it and modify spec in the edit page and save.
"dependencies": {
    "file": [
        {
            "type": "js",
            "path": "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-beta1/jquery.min.js",
            "name": "$"
        },
        {
            "type": "js",
            "path": "https://d3js.org/d3.v4.min.js",
            "name": "d3"
        }
    ]
}
The first dependency is jQuery with version 3, which is default. The second one is for d3 with version 4.
In the “script” tab, there are 3 default functions:_init(), _close() , and doSomething(). Add theses codes to the _init method and save.
let d3 = this.api.imports.d3; // declare namespace
d3.select("body").style("background-color", "deeppink")
    .selectAll("p")
    .data([1, 2, 3, 4, 5])
    .enter().append("p")
        .text(function(d) {
            return `Hello, I'm number ${ d }!`;
        }).style("color", "white");
In the “inner html” tab, delete everything in it or add everything you want. This is kind of inside the body block. Save it
In the “studio” page. create an Xap. Add this component to the dataflow. Go to preview, hooray !

JavaScript in Exapitve

This page explains the “spec” in details, especially the dependency about url and asset.
this page explains the JavaScript API in the script:
this.api.inputState.export()
this.api.layoutElement
this.api.imports  
this.api.log( msg, value ) 
this.api.warning( msg, value )
this.api.error( msg, value ) 
this.api.output( name, value )
this.api.value
this.api.dataflow.setLayout( layoutSpec )

Decompose existing components

FileDropTarget

100 lines, mostly deal with binary strings.
I would like to use file drop. js to encapsulate the codes.

CSVParser

reuse of Papa.Parse

Scatterplot

based on D3.js, with 2 helper scripts: tinycolor, visUtil (hosted at AWS).
The basic architecture :
explort default {
      _init(){} // 400 lines
    resize(){}
    data(){}
    brushExtents(){}
    options(){}
    select(){}
}
I trace the data flow by the key word “export”,
data = this.api.inputState.export().data; // line 349
this.updateOptions(this.inputState.export()); // line 420
var brushExtents = this.api.inputState.get('brushExtents').export(); //line 434
this.updateOptions(this.inputState.export()); // line 438
select(){ this.onSelect( this.api.inputState.get("select").export() ); } //446
and by the key word “output”,
_this.api.output("brushExtents", {
  x: empty ? [] : x,
  y: empty ? [] : y
}); // line 96, within function brushend()
nodes.on("mouseover", function(d) {api.output("mouseover", [d.projectedId]);d3.select(this).classed("highlight", true);})
.on("mouseout", function(d){api.output("mouseout", [d.projectedId]);
  d3.select(this).classed("highlight", false);})
.on("click", function(d){api.output("click", [d.projectedId]); //line 266
this.api.output("selected", selected[0].map(function(d){ return d.__data__.projectedId;})); // line 344
I still couldn’t fully understand the codes. It heavily uses D3 to manipulate data and mapping. And there is some confusion for the use of this.api, api, this and _this, due to the need of creating a copy?
Another thing is this component use vis-util library, to use class visUtil.Axes, visUtil.Brush for drawing. However, this library seems not very popular because there is very few sources about it. And no official website!
tinycolor library seems popular with 1536 stars in GitHub. But weird thing is why I didn’t see the related scripts?
By the way, Stacked/Grouped Barchart uses d3, velocity, visUtil, vis libraries.

My Xap

Dimple_xap

The initial difficulty I encountered was how to feed data into high-level library based codes such as pandas.read_table(file)or d3.tsv(file,function).Because FileDropTarget component already “half-process” the file, and CSVParser make it into a JSON type data stream. I just don’t want to reverse duffles back into file.
After some exploration, I figured it out that I can host the data file in my github, get a raw file link, and use some commands to directly read from the URL. For Python, there are 2 ways:
# recommended way
import StringIO as io  # import io if using python 3
import requests
import pandas as pd
url="https://raw.githubusercontent.com/cs109/2014_data/master/countries.csv"
s=requests.get(url).content
c=pd.read_csv(io.StringIO(s.decode('utf-8')))

# not recommended, write data into a file storing somewhere
import urllib2
response = urllib2.urlopen(url)
data = response.read()
filename = "t.txt"
with open(filename, 'w') as f:
    f.write(data)  # Write data to file
df = pd.read_table(filename)
For Javascript,
d3.tsv("world_cup.tsv", draw);  // file in local disk
d3.tsv("https://raw.githubusercontent.com/jychstar/datasets/master/titanic/world_cup.tsv", draw); // file hosted at github
draw(JSON_dataset);  // direct read JSON dataset/list of dictionaries
After trial and error, I finally make my first Xap work. It only includes a JavaScript Component, the script inside the export_default{}; is:
_init() {
  let d3 = this.api.imports.d3;
  let dimple = this.api.imports.dimple;
  function draw(data) {
  "use strict";
  var svg = d3.select("body").append("svg")
      .attr("width", 1400).attr("height", 600);
  svg.append("text").attr("x", 700).attr("y", 30).attr("text-anchor", "middle").style("font-size", "30px").style("font-weight", "bold").text("World Cup Attendance vs. Year");
  var myChart = new dimple.chart(svg, data);
  var x = myChart.addTimeAxis("x", "year");
  var y = myChart.addMeasureAxis("y", "attendance");
  x.dateParseFormat = "%Y";
  x.tickFormat = "%Y";
  x.timeInterval = 4;
  x.fontSize = 20;
  y.fontSize = 20;
  myChart.addSeries(null, dimple.plot.line);
  myChart.addSeries(null, dimple.plot.scatter);
  myChart.addSeries(null, dimple.plot.bar);
  myChart.draw();
  }
var url = "https://raw.githubusercontent.com/jychstar/datasets/master/titanic/world_cup.tsv";
 d3.tsv(url, draw);   
},
The dependencies is:
"dependencies": {
    "file": [
        {
            "type": "js",
            "path": "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-beta1/jquery.min.js",
            "name": "$"
        },
        {
            "type": "js",
            "path": "https://d3js.org/d3.v4.min.js",
            "name": "d3"
        },
        {
            "type": "js",
            "path": "https://cdnjs.cloudflare.com/ajax/libs/dimple/2.3.0/dimple.latest.min.js",
            "name": "dimple"
        }
    ]
},

Titanic_xap, to be continued

My original plan is to implement what I can do in a Jupyter notebook: https://github.com/jychstar/datasets/blob/master/titanic/Titanic%2C%20from%20Kaggle.ipynb
It is cool and have the mouse-over feature. However, the barplot is not exactly what I want. I realize the seaborn.factorplot and dimple.plot.bar have their own concepts of even the seemly similar thing. There is a huge gap between different language communities.
​

Wednesday, March 8, 2017

Dimple JavaScript library

During the building of my first Xap, I became a huge fan of Dimple. I think it deserves a full post and spin it off from my previous post: Data Analyst ND 3, data visualization by D3.

dimple.js

Dimple is only one of the JavaScript charting frameworks. I am not sure whether it is the best. I choose it only because I know it from udacity. According to the wiki page of its github, its 1.0 version was released on 2013.9.5, current version is 2.3, released on 2016.12.16.

udacity: basic chart example

Set up a local server because sometimes browser will prevent loading local JavaScript files due to security reasons. Some start codes are provided at basic_charts.zip.
cd Desktop/Udacity/DAND/P6_lesson/basic_charts/
python -m SimpleHTTPServer # python 2.x
python -m http.server  # python 3.x
note: Sometimes use python to host a local server will return error: “Address already in use”, which means the default port: 8000 is occupied by whatever reason. A way to find process is ps -fA | grep python and kill xxxxx But it may not work. Alternatively, use another port between 1024 and 8000, such as python -m SimpleHTTPServer 1024
  • open localhost:8000
  • add debugger; in the function draw() of html file
  • console.table(data) in the browser console to check data
The polished codes are:
function draw(data) {
    "use strict";
    var svg = d3.select("body").append("svg")
        .attr("width", 1400).attr("height", 600); // creat a div of 1400*600
      // var svg = dimple.newSvg("body", 1400, 600); // dimple way
    svg.append("text").attr("x", 700).attr("y", 20).attr("text-anchor", "middle"). style("font-size", "30px").style("font-weight", "bold")
    .text("World Cup Attendance vs. Year"); // add title in specified location

    var myChart = new dimple.chart(svg, data); // create a dimple chart object
    var x = myChart.addTimeAxis("x", "year"); // add column year as x
    var y = myChart.addMeasureAxis("y", "attendance"); // add column attendance as y
    x.dateParseFormat = "%Y";
    x.tickFormat = "%Y";  // change tick format
    x.timeInterval = 4;
    x.fontSize = 20;
    y.fontSize = 20;
    myChart.addSeries(null, dimple.plot.line);    //group, plot type
    myChart.addSeries(null, dimple.plot.scatter);
    myChart.addSeries(null, dimple.plot.bar);
    myChart.draw();
} // end draw()
// d3.tsv("world_cup.tsv", draw); // parse local file & apply draw() 
var url = "https://raw.githubusercontent.com/jychstar/datasets/master/titanic/world_cup.tsv"
d3.tsv(url, draw); // parse raw file from internet
  • traditional Journalism: Data around narrative, physical/static
  • data Journalism: Narrative around data, interactive, openweb

official document and examples

The official GitHub gives a lot of interesting examples. It’s tons of fun to play with the animation. I just list a few basic syntax below. A quick note: in Udacity course, they set a= null in myChart.addSeries(a,b), which is prone to errors. So always pass something to the first parameter.
dimple.plot.bar
mouse over animation code see advanced_bar_labels
var myChart = new dimple.chart(svg, data),
var x = myChart.addTimeAxis("x", "year");
var x = myChart.addCategoryAxis("x", ["Price Tier", "Channel"]);
var y = myChart.addPctAxis("y", "Unit Sales");
var y = myChart.addMeasureAxis("y", "Unit Sales"),
var s = myChart.addSeries("Owner", dimple.plot.bar);

myChart.addLegend(200, 10, 380, 20, "right");
myChart.draw();
dimple.plot.line
x.addOrderRule("Date");
// Min price will be green, middle price yellow and max red
myChart.addColorAxis("Price", ["green", "yellow", "red"]);
// Add a thick line with markers
var lines = myChart.addSeries("Owner", dimple.plot.line);
lines.lineWeight = 5;
lines.lineMarkers = true;
dimple.plot.bubble
mouse over animation code see advanced_interactive_legends
myChart.addMeasureAxis("x", "Price");
myChart.addMeasureAxis("y", "Sales Value");
myChart.addSeries("Owner", dimple.plot.bubble);
​

Saturday, March 4, 2017

First experience with Exaptive platform

Why Exaptive?

I always feel excited to explore new things. As a data scientist, I am now trying to learn a web-based tool to increase my productivity, although learning itself takes time.
Exaptive is developing a platform that enables data scientist to build customized tools for themselves. Why build such a platform? Because a data science project usually includes data wrangling, data mining and data visualization. You need different APIs at different stages, you write your own scripts here and there. And for the last step, data visualization, you probably need to display scalable and interactive graphs on web to reach more audiences. This means you need to change Python/R to JavaScript with D3. So, to have a seamless workflow, isn’t it nice to have all the pieces in one place?
There is no magic wand in the world that can turn arbitrary format, unknown quality dataset into a pleasing insight. Human invent various tools to make the process easier. Existing tools like Microsoft Excel and Tableau are great. But they only provide limited customized options. So why not decompose them a little bit and remix the components as you wish? This is exactly what Exaptive is trying to accomplish. Let’s dive in.

First look of Exaptive

Open https://exaptive.city/, there are 4 options at the top:
  • Home. Empty here unless you have created your Xap.
  • Studio. Empty first. When you click + button, there pops up there things: Component, Xap, Asset. Component is the basic building block. Xap is the product when you piece required components together. Asset is dataset, code snippet, pictures that are used to build component or feed data. The latest version is 4.0.24, released on 2016.8.29
  • Explore. A collection of pre-built xap, component, assent. You can add them into your own Studio. Currently, there are 100 public modules , among which 16 are Xaps.
  • Learn. Tutorials, Documentations, Discussion (226 bug reports, 107 feature requests, 17 general discussion. This means an early stage of development)
I first read some documentations to get some basic concepts such as Entity-Attribute-Value data model, duffles( packed data from one component to another), primitive data types and containers, special treatment for Python (only for v 2.7, dependency, etc).
Then the best way to learn is to exercise with some workable examples, instead of building from scratch. Because these components and interfaces are designed with “biases” in mind. Learning should be like in our childhood that curiosity drives us to break down everything to see what’s inside the black box, even if parents will nag about the mess we make.

Demystify: Pub Med Result List Example

Go to “Explore” page, “Pub Med Result List Example” XAP appear first. Let’s try it and add it to Studio.
Go to Studio page, we see the “Pub Med” is there. We have 4 choices: info (click name string), run (click “play” icon), edit (click ‘hammer’ icon), delete (“trash can”).
On “info“ page, which shows the components that are used: Text Box, Button, PubMed Search, Result List. We can simply infer their functions from the names. “layout” shows some HTML codes, which will be inserted into
<body data-gr-c-s-loaded='true'> == $0
  <div class = "exaptive-doc">
    <div class = "exaptive-doc-main">
      <div data-node>
        <!-- layout codes -->
      </div>
    </div>
  </div>
</body>
if you parse the page when run Xap. The “layout” codes construct the front-end interface on webpage and link to the back-end modules.
On run page, you see a search input and button. Obviously, this is a customized search engine based on PubMed.
On edit page under dataflow tab, as the name, this is where the data flows. These boxes and wiring immediately remind me a software with a simiar graphical interface: Labview. During my doctoral research, one of my proudest work is that I wrote a Labview program that had improved the data collection efficiency by more than 10 times. It not only reduces the tedious work, but also help me discover new phenomenon by refining the resolution.
Labview aims for the electrical signals that are parsed by the National Instrument hardware. It is a powerful tool for electrical engineer. I can imagine how data engineers feel empowered if a “data” version of the Labview is at their hands. I am super excited with the opportunity to contribute to its early development. We can borrow some concepts from Labview and implement exaptively!
Go back to my topic on dataflow tab. We can intuitively see the input nodes and output nodes for each component. When you hover over a component, it shows name for each node and a row of short cut buttons: info, suggestions, edit, setting and remove. You can click on the node or double click the component to see the data type, attribute, values for each node, and possible version numbers.
The secret sauce is revealed in the edit of the component. Take “PubMed Search_0” component as an example. We see:
  • description (baisc usage, output fields, output example in JSON format, developers: Matt & Frank)
  • inputs
  • outputs
  • script (python codes, use xmltodict module to parse data),
  • spec (main, domain, dependency, input, output, etc).
Note that the output fields in the description are different from outputs. At this moment, I don’t know where exactly these python codes are executed. I guess it is wrapped in the exaptive.js somewhere else. There must be some sort of glue codes to connect inputs, python codes and outputs.
The “ResultList_0” component is written in JavaScript in the script. It is strange to me that TextBox and Button component are empty in the edit tab, and sometimes mistakenly display other compoenent (e.g.PubMed Search)’s information.
To sum up, this is what a customized search engine is composed of. If you want to modified it for other domains such as astrophysics or politics, you will need to revise the python scripts, especially for the XML sources and tabs.

Tutorial: build your first Xap

Steps to follow:
  1. download a csv file. It has 3818 instances , 24 columns (11 numerical), some missing values.
  2. in the Explore page, add some pre-built components to Studio:File Drop Target, CSV Parser, Button, Scatterplot, Modal (look for the one that's black and white),Tooltip, Table.
  3. in the Studio page, create an Xap, open it, rename it
  4. Go to DataFlow tab, drop the above components, try following 2 wiring.
  5. FileDropTarget.FileData->CSVParser.data—result-> Button.value —click->Table.data. save, run, load csv file. After you see how table works, delete table component .
  6. FileDropTarget->CSVParser-> Button->Scatterplot, click button in the “preview” tab, wait until you see something in the plot (means data is loaded).
  7. If data is correctly parsed, it shows “20/3181 entities| 20/24 attributes” after the “data” input node. 20 means the 20 samples are showed underneath. Expand “data” node by click, set x= accommodates, y=price, color = room_type. Go to “preview” tab to see the magic.
  8. In styple tab, add <br> style ="height:75%;"</br>before button tag. save and see the magic in ‘preview’ tab.
  9. Set data.mouseover = street. Add tooltip and data gates to Dataflow. Add 2 wiring : scatterplot.mouseover -> dataMergeGate (expression: x0[0]) -> tooltip.html; scatterplot.mouseoutput -> tooltip.hide. Go to ‘preview’ tab, pretty cool!
  10. In scatterplot.options, set "brush": true. Add table component back. wire: scatterplot.selected -> table.data. Go to ‘preview’, hold and drag to select multiple points, see the magic.
  11. visualize price distribution in areas. Set data.x= longitude, data.y= latitude, axes.x.hidden: true, axes.y.hidden: true. Add a new scatterplot, wire: scatterplot_0.selected -> scatterplot_1.data. So the selected data will be plotted. In scatterplot_1, set data.x = accommodate, data.y = price, data.color = room_type, axes.x.text: "Accommodate", axes.y.text: "Price($)". play around in “preview” tab.
  12. Use Modal component to place 2 plots in 2 different layers. This is very powerful to manage visual complexity. Add Modal component, set options.fullScreen: true,options.hideHeader:true. Add Button component, set options.text: "Add or Send Data". Do 2 wiring: button_1.click ->Modal.open, button_2.click -> Modal.close. This is to close the modal after data is sent, so as to prevent the port from saving the data.
  13. In the “style” page, change html code snippet to:
    <button data-node="Button_1"></button>
    <div data-node="Modal_0">    
       <div data-node="FileDropTarget_0"></div>    
       <button data-node="Button_0"></button>
    </div>
    
    <svg data-node="Scatterplot_0" style="height: 50%;"></svg>
    <div data-node="Tooltip_0"></div>
    
    From the code sequence, you can see Button_1 is first executed to open Modal_0, within which the FileDropTarget and Button_0 functions. This ensure the dataflow sequence.
  14. Add another Modal component. wiring: Scatterplot_0.selected -> Modal_1.open. This will trigger Modal_1 to open when new data is received. Set `options.title:”price vs accommodation”. Add these html codes into “style” page.
    <div data-node="Modal_1" style="height: 45%; width: 75%;">    
       <div data-node="Scatterplot_1" style="height: 90%; width: 100%;"></div>    
    </div>
    
    Note that the tutorial has a typo which misspell “45%, 75%” as “450px,750px”.
  15. Add Text to the front-end html. In “style” page, add following to HTML:
    <h3 class = "text">
     A Map by AirBNB
    </h3>
    <p class= "text">
     click and drag accross the visualization to sse more information
    </p>
    
    And add .text{text-align: center;} to CSS.
  16. Save & Publish.
  17. In “scatterplot” component, at data.points, click the funnel icon to add filter, or key icon to add id.
    Entity Filer: price < 150 && room_type == "Entire home/apt", Value Selector: room_type == "Private bedroom" ? "star" : "triangle"
Note for the essential component “Scatterplot”: The vsiualization is based on D3.js, with 2 helper scripts: tinycolor, visUtil (created by Exaptive).

Tutorial: So You’re Comfortable with the Exaptive Fundamentals

After watch a few video clips, I realized this tutorial is out-dated. Some Components are not there, such as Quandle Stock Prices, Bar char, Duffle Join. Some videos even don’ t play.
The interesting thing is the TwitterSearchAPI-> wordFrequency-> word cloud, which shows the words with size proportional to thier frequency.

Tutorial: build a Python Component

  1. In Studio page, add a python component, rename it, add description
  2. In edit page -> spec, install python modules in Docker by adding following scripts:
    "dependencies":{
          "apt": [{"path": "libffi-dev"},
                {"path": "libssl-dev"}],
        "pip": [{"path": "numpy"},
                {"path": "quandl"}],
        "file":[]
    },
    
    When you click save, it, the environement will be built, which may take a while. Note: in the latest python domain, ‘gfortran’ is pre-installed.
  3. In edit page-> inputs, revise the defaut input “count” to “call”:
    Name: call
    value type: entity<list tickers, string startDate, string endDate, string APIKey, string frequency>
    default: {"tickers":["AAPL","MSFT"], "startDate": "2011-12-12", "endDate":"2016-05-05", "APIKey": "tE4dug_G3e-gcf72vq7g", "frequency":"monthly"}
    
    If granular inputs is checked, the input ports will explicitly display these attributes.
  4. In edit page -> script, replace them by :
    import urllib2
    import json
    def call(self):
        call = self.api.inputstate.export()['call'] 
        tickers = call['tickers']  
        start_date = call['startDate']
        end_date = call['end_date']
        APIKey = call['frequency']
    
        base = "http://www.quandl.com/api/v3/datasets/WIKI/"
    
        data = []
        for i in tickers:
            response = urllib2.urlopen(base+i+'.json?'+'start_date='+start_date+'&end_date'+end_date+'&collapse='+
                                       frequency+"&api_key="+APIKey)
            response_data = json.loads(response.read())
            data.append(response_data)
    
        arrEnt = []
    
        for ticker in data:
            ticker_data = ticker['dataset']['data']
            ticker_columns = ticker['dataset']['column_names']
            ticker_symbol = ticker['dataset']['dataset_code']
    
            for line in ticker_data:
                counter = 0;
                info ={'Stock':ticker_symbol}
                while counter < len(ticker_columns):
                    info[ticker_columns[counter]] = line[counter]
                    counter += 1
                arrEnt.append(info)
    
        duffle = self.api.value.multiset(arrEnt)
        self.api.output("data", duffle)
    
    What it does is read a dictionary containing the requested information. Use urllib2.urlopen to crawl information from webpage, use json.loads to parse the webpage. Each ticker corresponds to a dataset, which is a dictioary with 21 keys. Among 21 keys, the column name and data are the most important, and each is a list of 105 items. Rearrange this information to produce a list “arrEnt”. Each element in arrEnt is a dictionary “info”. “arrEnt” is wrapped into duffle and output.
  5. Build an Xap with this python Component and a LineChart Component.

The Exaptive Python Data API

When an input is activated by data being sent into that port, the component will attempt to call a method defined in the script by the same name. That is, if your input port is named my_data, then the component will attempt to call a method named my_data.
Usually the first line of code is: state = self.api.inputstate.export() This gets an input port state. self here corresponds to the main argument to your method.
The last line of code is: self.api.output("output_name", my_output) This sends my_output to the output port named “output_name”.
some other commonly-seen API codes:
self.api.value(my_variable) # Casting data into exaptive data model
self.api.imports['datafile']  # datafile is an asset that you pre-define in the "dependencies"-> "file"
slef.api.log("this is a log", variable) # output to the log messages tab, which locates at the bottom right of the dataflow page. It's a little icon and looks like a logbook.

Tutorial: Data Analysis in Python

  1. create a python component in Studio, name it “chopstick”, modify “dependencies” in spec:
    "dependencies": {
      "apt": [{"path": "python-numpy"},
                  {"path": "python-scipy"}],
       "pip": [{"path": "scikit-learn"}], 
       "file": []
      },
    
  2. rename input from “count” to “data”. And because the python function is triggered by the input port with the same name, we need to rename the function and tinker with it in the script:
    from sklearn import cluster
    import numpy as np
    def data(self):
        data = self.api.inputstate.export()["data"]
        duffle = []
        self.api.output("data", duffle)
    
    self here seems werid for python beginner. What is the top-level class and how the class is initialized? My guess is that when you create a python component, the backend of the Exaptive Studio is actually calling a class constructor to initialize it. Also rename output to “duffle”
  3. create a nex Xap in Studio, then go to DataFlow in Edit page. Add components and wire as: AssetLoader.data -> CSVParser.data - -result -> chopstick.data
  4. Double click AssetLoader and write f89fd760-8cab-11e6-a897-2dbff63efc07 into “uuid” input port. click the arrow buttion nearby (this logo is somewhat confusing to me, I first reaction is that it will lead me to a new page, which is the norm in the internet ). What it actually does is feeding the source and trigger the flow. You will see several ports light up blue, which means the data flow through these ports. When you click at a single port, you can see the value in it. For this case, we can see CSVParser.result has 186 entities and 3 attributes, among which 20 entities are displayed when you further click.
  5. Hover over “chopstick” component, open the edit page and edit the script.
    To better understand the essential codes for data analytics, I practise them in a python notebook, link
  6. Add a “table” component… It seems this tutorial is not finished.

Tutorial: Using a Visualization to Trigger Events

This tutorial actually doesn’t cover much about visualization. I would suggest follow the first tutorial “build your first Xap” for visualization purpose. What interests me is how the “Iris Sample Dataset” component is built. In this case, the input port is named “trigger”. In the same name function, data is directly loaded from sklearn.datasets, then is reorganized into a list of dictionary.

Some handy tricks

  1. In “dataflow” page, there are “+O-“ buttons at the bottom left. So you can resize these boxes. If they are off the center, you can click anywhere in the blank space, hold it and drag the whole stuff to the center.
​