Whiskey Data

This data set contains data on a small number of whiskies


In [7]:
import pandas as pd
from numpy import log, abs, sign, sqrt
import ibmcognitive

ibmcognitive.brunel.set_brunel_service_url("http://localhost:8080/BrunelServices")

data = pd.read_csv("data/whiskey.csv")

print('Data on whiskies:', ', '.join(data.columns))


---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-7-5dc1b1df4799> in <module>()
      3 import ibmcognitive
      4 
----> 5 ibmcognitive.set_brunel_service_url("http://localhost:8080/BrunelServices")
      6 
      7 data = pd.read_csv("data/whiskey.csv")

AttributeError: 'module' object has no attribute 'set_brunel_service_url'

Summaries

Shown below are the following charts:

  • A treemap display for each whiskey, broken down by country and category. The cells are colored by the rating, with lower-rated whiskies in blue, and higher-rated in reds. Missing data for ratings show as black.
  • A filtered chart allowing you to select whiskeys based on price and category
  • A line chart showing the relationship between age and rating. A simple treemap of categories is linked to this chart
  • A bubble chart of countries linked to a heatmap of alcohol level (ABV) by rating

In [2]:
brunel x(country, category) color(rating) treemap label(name:3) tooltip(#all) style('.label {font-size:7pt}') legends(none):: width=900, height=600


[HTTP ERROR:404][HTTP ERROR:404][HTTP ERROR:404]
---------------------------------------------------------------------------
HTTPError                                 Traceback (most recent call last)
/Users/graham/Projects/Cognitive/brunel/python/org/brunel.py in brunel_service_call(baseURL, queryParams, data, attempts, sleep)
     91         req = urllib.request.Request(url, data, headers)
---> 92         response = urllib.request.urlopen(req)
     93         return response

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/urllib/request.py in urlopen(url, data, timeout, cafile, capath, cadefault)
    152         opener = _opener
--> 153     return opener.open(url, data, timeout)
    154 

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/urllib/request.py in open(self, fullurl, data, timeout)
    460             meth = getattr(processor, meth_name)
--> 461             response = meth(req, response)
    462 

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/urllib/request.py in http_response(self, request, response)
    570             response = self.parent.error(
--> 571                 'http', request, response, code, msg, hdrs)
    572 

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/urllib/request.py in error(self, proto, *args)
    498             args = (dict, 'default', 'http_error_default') + orig_args
--> 499             return self._call_chain(*args)
    500 

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/urllib/request.py in _call_chain(self, chain, kind, meth_name, *args)
    432             func = getattr(handler, meth_name)
--> 433             result = func(*args)
    434             if result is not None:

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/urllib/request.py in http_error_default(self, req, fp, code, msg, hdrs)
    578     def http_error_default(self, req, fp, code, msg, hdrs):
--> 579         raise HTTPError(req.full_url, code, msg, hdrs, fp)
    580 

HTTPError: HTTP Error 404: Not Found

During handling of the above exception, another exception occurred:

HTTPError                                 Traceback (most recent call last)
/Users/graham/Projects/Cognitive/brunel/python/org/brunel.py in brunel_service_call(baseURL, queryParams, data, attempts, sleep)
     91         req = urllib.request.Request(url, data, headers)
---> 92         response = urllib.request.urlopen(req)
     93         return response

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/urllib/request.py in urlopen(url, data, timeout, cafile, capath, cadefault)
    152         opener = _opener
--> 153     return opener.open(url, data, timeout)
    154 

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/urllib/request.py in open(self, fullurl, data, timeout)
    460             meth = getattr(processor, meth_name)
--> 461             response = meth(req, response)
    462 

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/urllib/request.py in http_response(self, request, response)
    570             response = self.parent.error(
--> 571                 'http', request, response, code, msg, hdrs)
    572 

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/urllib/request.py in error(self, proto, *args)
    498             args = (dict, 'default', 'http_error_default') + orig_args
--> 499             return self._call_chain(*args)
    500 

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/urllib/request.py in _call_chain(self, chain, kind, meth_name, *args)
    432             func = getattr(handler, meth_name)
--> 433             result = func(*args)
    434             if result is not None:

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/urllib/request.py in http_error_default(self, req, fp, code, msg, hdrs)
    578     def http_error_default(self, req, fp, code, msg, hdrs):
--> 579         raise HTTPError(req.full_url, code, msg, hdrs, fp)
    580 

HTTPError: HTTP Error 404: Not Found

During handling of the above exception, another exception occurred:

HTTPError                                 Traceback (most recent call last)
<ipython-input-2-b74df99535f7> in <module>()
----> 1 get_ipython().magic("brunel x(country, category) color(rating) treemap label(name:3) tooltip(#all) style('.label {font-size:7pt}') legends(none):: width=900, height=600")

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/IPython/core/interactiveshell.py in magic(self, arg_s)
   2305         magic_name, _, magic_arg_s = arg_s.partition(' ')
   2306         magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
-> 2307         return self.run_line_magic(magic_name, magic_arg_s)
   2308 
   2309     #-------------------------------------------------------------------------

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/IPython/core/interactiveshell.py in run_line_magic(self, magic_name, line)
   2226                 kwargs['local_ns'] = sys._getframe(stack_depth).f_locals
   2227             with self.builtin_trap:
-> 2228                 result = fn(*args,**kwargs)
   2229             return result
   2230 

/Users/graham/Projects/Cognitive/brunel/python/ibmcognitive/magics.py in brunel(self, line, cell)

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/IPython/core/magic.py in <lambda>(f, *a, **k)
    191     # but it's overkill for just that one bit of state.
    192     def magic_deco(arg):
--> 193         call = lambda f, *a, **k: f(*a, **k)
    194 
    195         if callable(arg):

/Users/graham/Projects/Cognitive/brunel/python/ibmcognitive/magics.py in brunel(self, line, cell)
     56         if data is None:
     57             data = self.best_match(self.get_vars(action), list(datas.values()))
---> 58         return brunel.display(action, data, width, height, output)
     59 
     60 

/Users/graham/Projects/Cognitive/brunel/python/org/brunel.py in display(brunel, data, width, height, output)
     78     elif output == 'd3':
     79         queryParams['visid'] = visid
---> 80         response = brunel_service_call(BRUNEL_BASEURL + '/d3?', queryParams, csv)
     81         return d3_output(response, visid, width, height)
     82     else:

/Users/graham/Projects/Cognitive/brunel/python/org/brunel.py in brunel_service_call(baseURL, queryParams, data, attempts, sleep)
     96         if attempts > 1:
     97             time.sleep(sleep)
---> 98             return brunel_service_call(url, queryParams, data, attempts - 1, sleep)
     99         else:
    100             raise

/Users/graham/Projects/Cognitive/brunel/python/org/brunel.py in brunel_service_call(baseURL, queryParams, data, attempts, sleep)
     96         if attempts > 1:
     97             time.sleep(sleep)
---> 98             return brunel_service_call(url, queryParams, data, attempts - 1, sleep)
     99         else:
    100             raise

/Users/graham/Projects/Cognitive/brunel/python/org/brunel.py in brunel_service_call(baseURL, queryParams, data, attempts, sleep)
     90     try:
     91         req = urllib.request.Request(url, data, headers)
---> 92         response = urllib.request.urlopen(req)
     93         return response
     94     except HTTPError as e:

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/urllib/request.py in urlopen(url, data, timeout, cafile, capath, cadefault)
    151     else:
    152         opener = _opener
--> 153     return opener.open(url, data, timeout)
    154 
    155 def install_opener(opener):

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/urllib/request.py in open(self, fullurl, data, timeout)
    459         for processor in self.process_response.get(protocol, []):
    460             meth = getattr(processor, meth_name)
--> 461             response = meth(req, response)
    462 
    463         return response

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/urllib/request.py in http_response(self, request, response)
    569         if not (200 <= code < 300):
    570             response = self.parent.error(
--> 571                 'http', request, response, code, msg, hdrs)
    572 
    573         return response

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/urllib/request.py in error(self, proto, *args)
    497         if http_err:
    498             args = (dict, 'default', 'http_error_default') + orig_args
--> 499             return self._call_chain(*args)
    500 
    501 # XXX probably also want an abstract factory that knows when it makes

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/urllib/request.py in _call_chain(self, chain, kind, meth_name, *args)
    431         for handler in handlers:
    432             func = getattr(handler, meth_name)
--> 433             result = func(*args)
    434             if result is not None:
    435                 return result

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/urllib/request.py in http_error_default(self, req, fp, code, msg, hdrs)
    577 class HTTPDefaultErrorHandler(BaseHandler):
    578     def http_error_default(self, req, fp, code, msg, hdrs):
--> 579         raise HTTPError(req.full_url, code, msg, hdrs, fp)
    580 
    581 class HTTPRedirectHandler(BaseHandler):

HTTPError: HTTP Error 404: Not Found

In [ ]:
brunel bubble color(rating:red) sort(rating) size(abv) label(name:6) tooltip(#all) filter(price, category) :: height=500

In [ ]:
%%brunel 
line x(age) y(rating) mean(rating) label(country) split(country) using(interpolate) bin(age:8) color(#selection) legends(none) 
| treemap x(category) interaction(select) size(#count) color(#selection) legends(none) sort(#count:ascending) bin(category:9)
        tooltip(country) list(country) label(#count) style('.labels .label {font-size:14px}')
:: width=900

In [ ]:
%%brunel 
bubble label(country:3) bin(country) size(#count) color(#selection) sort(#count) interaction(select) tooltip(name) list(name) legends(none)
| x(abv) y(rating) color(#count:blue) legends(none) bin(abv:8) bin(rating:5) style('symbol:rect; stroke:none; size:100%')  at(0,10,70,100)
        interaction(select) label(#selection) list(#selection)  at(60,15,100,100) tooltip(rating, abv,#count) legends(none) 
|  bar label(brand:70) list(brand) at(0,0, 100, 10) axes(none) color(#selection) legends(none) interaction(filter)
:: width=900, height=600

Some Analysis

Here we use the sci-kit decision tree regression tool to predict the price of a whiskey given its age, rating and ABV value. We transform the output for plotting purposes, but note that the tooltips give the original data


In [3]:
from sklearn import tree
D = data[['Name', 'ABV', 'Age', 'Rating', 'Price']].dropna()
X = D[ ['ABV', 'Age', 'Rating'] ]
y = D['Price']
clf = tree.DecisionTreeRegressor(min_samples_leaf=4)
clf.fit(X, y)
D['Predicted'] = clf.predict(X)
f = D['Predicted'] - D['Price']
D['Diff'] = sqrt(abs(f)) * sign(f)
D['LPrice'] = log(y)
%brunel y(diff) x(LPrice) tooltip(name, price, predicted, rating) color(rating)  :: width=700


[HTTP ERROR:404][HTTP ERROR:404][HTTP ERROR:404]
---------------------------------------------------------------------------
HTTPError                                 Traceback (most recent call last)
/Users/graham/Projects/Cognitive/brunel/python/org/brunel.py in brunel_service_call(baseURL, queryParams, data, attempts, sleep)
     91         req = urllib.request.Request(url, data, headers)
---> 92         response = urllib.request.urlopen(req)
     93         return response

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/urllib/request.py in urlopen(url, data, timeout, cafile, capath, cadefault)
    152         opener = _opener
--> 153     return opener.open(url, data, timeout)
    154 

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/urllib/request.py in open(self, fullurl, data, timeout)
    460             meth = getattr(processor, meth_name)
--> 461             response = meth(req, response)
    462 

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/urllib/request.py in http_response(self, request, response)
    570             response = self.parent.error(
--> 571                 'http', request, response, code, msg, hdrs)
    572 

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/urllib/request.py in error(self, proto, *args)
    498             args = (dict, 'default', 'http_error_default') + orig_args
--> 499             return self._call_chain(*args)
    500 

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/urllib/request.py in _call_chain(self, chain, kind, meth_name, *args)
    432             func = getattr(handler, meth_name)
--> 433             result = func(*args)
    434             if result is not None:

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/urllib/request.py in http_error_default(self, req, fp, code, msg, hdrs)
    578     def http_error_default(self, req, fp, code, msg, hdrs):
--> 579         raise HTTPError(req.full_url, code, msg, hdrs, fp)
    580 

HTTPError: HTTP Error 404: Not Found

During handling of the above exception, another exception occurred:

HTTPError                                 Traceback (most recent call last)
/Users/graham/Projects/Cognitive/brunel/python/org/brunel.py in brunel_service_call(baseURL, queryParams, data, attempts, sleep)
     91         req = urllib.request.Request(url, data, headers)
---> 92         response = urllib.request.urlopen(req)
     93         return response

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/urllib/request.py in urlopen(url, data, timeout, cafile, capath, cadefault)
    152         opener = _opener
--> 153     return opener.open(url, data, timeout)
    154 

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/urllib/request.py in open(self, fullurl, data, timeout)
    460             meth = getattr(processor, meth_name)
--> 461             response = meth(req, response)
    462 

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/urllib/request.py in http_response(self, request, response)
    570             response = self.parent.error(
--> 571                 'http', request, response, code, msg, hdrs)
    572 

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/urllib/request.py in error(self, proto, *args)
    498             args = (dict, 'default', 'http_error_default') + orig_args
--> 499             return self._call_chain(*args)
    500 

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/urllib/request.py in _call_chain(self, chain, kind, meth_name, *args)
    432             func = getattr(handler, meth_name)
--> 433             result = func(*args)
    434             if result is not None:

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/urllib/request.py in http_error_default(self, req, fp, code, msg, hdrs)
    578     def http_error_default(self, req, fp, code, msg, hdrs):
--> 579         raise HTTPError(req.full_url, code, msg, hdrs, fp)
    580 

HTTPError: HTTP Error 404: Not Found

During handling of the above exception, another exception occurred:

HTTPError                                 Traceback (most recent call last)
<ipython-input-3-c8f04750ef36> in <module>()
      9 D['Diff'] = sqrt(abs(f)) * sign(f)
     10 D['LPrice'] = log(y)
---> 11 get_ipython().magic('brunel y(diff) x(LPrice) tooltip(name, price, predicted, rating) color(rating)  :: width=700')

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/IPython/core/interactiveshell.py in magic(self, arg_s)
   2305         magic_name, _, magic_arg_s = arg_s.partition(' ')
   2306         magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
-> 2307         return self.run_line_magic(magic_name, magic_arg_s)
   2308 
   2309     #-------------------------------------------------------------------------

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/IPython/core/interactiveshell.py in run_line_magic(self, magic_name, line)
   2226                 kwargs['local_ns'] = sys._getframe(stack_depth).f_locals
   2227             with self.builtin_trap:
-> 2228                 result = fn(*args,**kwargs)
   2229             return result
   2230 

/Users/graham/Projects/Cognitive/brunel/python/ibmcognitive/magics.py in brunel(self, line, cell)

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/IPython/core/magic.py in <lambda>(f, *a, **k)
    191     # but it's overkill for just that one bit of state.
    192     def magic_deco(arg):
--> 193         call = lambda f, *a, **k: f(*a, **k)
    194 
    195         if callable(arg):

/Users/graham/Projects/Cognitive/brunel/python/ibmcognitive/magics.py in brunel(self, line, cell)
     56         if data is None:
     57             data = self.best_match(self.get_vars(action), list(datas.values()))
---> 58         return brunel.display(action, data, width, height, output)
     59 
     60 

/Users/graham/Projects/Cognitive/brunel/python/org/brunel.py in display(brunel, data, width, height, output)
     78     elif output == 'd3':
     79         queryParams['visid'] = visid
---> 80         response = brunel_service_call(BRUNEL_BASEURL + '/d3?', queryParams, csv)
     81         return d3_output(response, visid, width, height)
     82     else:

/Users/graham/Projects/Cognitive/brunel/python/org/brunel.py in brunel_service_call(baseURL, queryParams, data, attempts, sleep)
     96         if attempts > 1:
     97             time.sleep(sleep)
---> 98             return brunel_service_call(url, queryParams, data, attempts - 1, sleep)
     99         else:
    100             raise

/Users/graham/Projects/Cognitive/brunel/python/org/brunel.py in brunel_service_call(baseURL, queryParams, data, attempts, sleep)
     96         if attempts > 1:
     97             time.sleep(sleep)
---> 98             return brunel_service_call(url, queryParams, data, attempts - 1, sleep)
     99         else:
    100             raise

/Users/graham/Projects/Cognitive/brunel/python/org/brunel.py in brunel_service_call(baseURL, queryParams, data, attempts, sleep)
     90     try:
     91         req = urllib.request.Request(url, data, headers)
---> 92         response = urllib.request.urlopen(req)
     93         return response
     94     except HTTPError as e:

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/urllib/request.py in urlopen(url, data, timeout, cafile, capath, cadefault)
    151     else:
    152         opener = _opener
--> 153     return opener.open(url, data, timeout)
    154 
    155 def install_opener(opener):

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/urllib/request.py in open(self, fullurl, data, timeout)
    459         for processor in self.process_response.get(protocol, []):
    460             meth = getattr(processor, meth_name)
--> 461             response = meth(req, response)
    462 
    463         return response

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/urllib/request.py in http_response(self, request, response)
    569         if not (200 <= code < 300):
    570             response = self.parent.error(
--> 571                 'http', request, response, code, msg, hdrs)
    572 
    573         return response

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/urllib/request.py in error(self, proto, *args)
    497         if http_err:
    498             args = (dict, 'default', 'http_error_default') + orig_args
--> 499             return self._call_chain(*args)
    500 
    501 # XXX probably also want an abstract factory that knows when it makes

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/urllib/request.py in _call_chain(self, chain, kind, meth_name, *args)
    431         for handler in handlers:
    432             func = getattr(handler, meth_name)
--> 433             result = func(*args)
    434             if result is not None:
    435                 return result

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/urllib/request.py in http_error_default(self, req, fp, code, msg, hdrs)
    577 class HTTPDefaultErrorHandler(BaseHandler):
    578     def http_error_default(self, req, fp, code, msg, hdrs):
--> 579         raise HTTPError(req.full_url, code, msg, hdrs, fp)
    580 
    581 class HTTPRedirectHandler(BaseHandler):

HTTPError: HTTP Error 404: Not Found

Simple Linked Charts


In [ ]:
%%brunel bar x(country) y(#count)
    | bar color(category) y(#count) polar stack label(category) legends(none)
    :: width=900, height=300

In [ ]:


In [ ]:


In [ ]:


In [ ]:


In [ ]:


In [ ]:


In [ ]: