Skip to content

Commit

Permalink
Merge pull request #270 from CartoDB/v0.3.0b5
Browse files Browse the repository at this point in the history
Version bump: v0.3.0b5
  • Loading branch information
andy-esch committed Nov 2, 2017
2 parents 08ce3f5 + 4685cc3 commit 0027393
Show file tree
Hide file tree
Showing 28 changed files with 851 additions and 469 deletions.
2 changes: 1 addition & 1 deletion cartoframes/__version__.py
@@ -1 +1 @@
__version__ = '0.2.4b4'
__version__ = '0.3.0b5'
69 changes: 41 additions & 28 deletions cartoframes/context.py
Expand Up @@ -58,22 +58,18 @@
class CartoContext(object):
"""CartoContext class for authentication with CARTO and high-level operations
such as reading tables from CARTO into dataframes, writing dataframes to
CARTO tables, and creating custom maps from dataframes and CARTO tables.
Future methods interact with CARTO's services like
`Data Observatory <https://carto.com/data-observatory>`__, and `routing,
geocoding, and isolines <https://carto.com/location-data-services/>`__.
CARTO tables, creating custom maps from dataframes and CARTO tables, and
augmenting data using CARTO's `Data Observatory
<https://carto.com/data-observatory>`__. Future methods will interact with
CARTO's services like `routing, geocoding, and isolines
<https://carto.com/location-data-services/>`__, PostGIS backend for spatial
processing, and much more.
Manages connections with CARTO for data and map operations. Modeled
after `SparkContext
<https://jaceklaskowski.gitbooks.io/mastering-apache-spark/content/spark-sparkcontext.html>`__.
Example:
Create a CartoContext object::
import cartoframes
cc = cartoframes.CartoContext(BASEURL, APIKEY)
Attrs:
Attributes:
creds (cartoframes.Credentials): :obj:`Credentials` instance
Args:
Expand All @@ -92,6 +88,12 @@ class CartoContext(object):
Returns:
:obj:`CartoContext`: A CartoContext object that is authenticated
against the user's CARTO account.
Example:
Create a CartoContext object::
import cartoframes
cc = cartoframes.CartoContext(BASEURL, APIKEY)
"""
def __init__(self, base_url=None, api_key=None, creds=None, session=None,
verbose=0):
Expand All @@ -118,24 +120,28 @@ def _is_org_user(self):

def read(self, table_name, limit=None, index='cartodb_id',
decode_geom=False):
"""Read tables from CARTO into pandas DataFrames.
Example:
.. code:: python
import cartoframes
cc = cartoframes.CartoContext(BASEURL, APIKEY)
df = cc.read('acadia_biodiversity')
"""Read a table from CARTO into a pandas DataFrames.
Args:
table_name (str): Name of table in user's CARTO account.
limit (int, optional): Read only ``limit`` lines from
``table_name``. Defaults to `None`, which reads the full table.
limit (int, optional): Read only `limit` lines from
`table_name`. Defaults to ``None``, which reads the full table.
index (str, optional): Not currently in use.
decode_geom (bool, optional): Decodes CARTO's geometries into a
`Shapely <https://github.com/Toblerity/Shapely>`__
object that can be used, for example, in `GeoPandas
<http://geopandas.org/>`__.
Returns:
pandas.DataFrame: DataFrame representation of `table_name` from
CARTO.
Example:
.. code:: python
import cartoframes
cc = cartoframes.CartoContext(BASEURL, APIKEY)
df = cc.read('acadia_biodiversity')
"""
query = 'SELECT * FROM "{table_name}"'.format(table_name=table_name)
if limit is not None:
Expand Down Expand Up @@ -572,15 +578,21 @@ def query(self, query, table_name=None, decode_geom=False):
operations (creating/dropping tables, adding columns, updates, etc.).
Args:
query (str): Query to run against CARTO user database.
query (str): Query to run against CARTO user database. This data
will then be converted into a pandas DataFrame.
table_name (str, optional): If set, this will create a new
table in the user's CARTO account that is the result of the
query. Defaults to None (no table created).
table in the user's CARTO account that is the result of the
query. Defaults to None (no table created).
decode_geom (bool, optional): Decodes CARTO's geometries into a
`Shapely <https://github.com/Toblerity/Shapely>`__
object that can be used, for example, in `GeoPandas
<http://geopandas.org/>`__.
Returns:
pandas.DataFrame: DataFrame representation of query supplied.
Pandas data types are inferred from PostgreSQL data types.
In the case of PostgreSQL date types, the data type 'object' is
used.
In the case of PostgreSQL date types, dates are attempted to be
converted, but on failure a data type 'object' is used.
"""
self._debug_print(query=query)
if table_name:
Expand Down Expand Up @@ -695,8 +707,9 @@ def map(self, layers=None, interactive=True,
``interactive`` is ``False``.
Returns:
IPython.display.HTML: Interactive maps are rendered in an
``iframe``, while static maps are rendered in ``img`` tags.
IPython.display.HTML or matplotlib Axes: Interactive maps are
rendered as HTML in an `iframe`, while static maps are returned as
matplotlib Axes objects or IPython Image.
"""
# TODO: add layers preprocessing method like
# layers = process_layers(layers)
Expand Down
4 changes: 3 additions & 1 deletion cartoframes/layer.py
@@ -1,6 +1,7 @@
"""Layer classes for map creation. See examples in `layer.Layer
<#layer.Layer>`__ and `layer.QueryLayer <#layer.QueryLayer>`__
for example usage.
for example usage for data layers. See `layer.BaseMap <#layer.BaseMap>`__ for
basemap layers.
"""

import pandas as pd
Expand Down Expand Up @@ -194,6 +195,7 @@ class QueryLayer(AbstractLayer):
If `color` is a :obj:`dict`, the following keys are options, with
values described:
- column (`str`): Column used for the basis of styling
- scheme (`dict`, optional): Scheme such as `styling.sunset(7)`
from the `styling module <#module-styling>`__ of cartoframes that
Expand Down
11 changes: 9 additions & 2 deletions docs/_sources/index.rst.txt
Expand Up @@ -9,18 +9,23 @@
:maxdepth: 2
:caption: Contents:

modules

CARTOFrames Functionality
=========================

CartoContext
------------
.. autoclass:: context.CartoContext
:members:
:member-order: bysource
:members: read, query, delete, map, data_augment

.. automethod:: write(df, table_name, temp_dir=SYSTEM_TMP_PATH, overwrite=False, lnglat=None, encode_geom=False, geom_col=None, \*\*kwargs)

Map Layer Classes
-----------------
.. automodule:: layer
:members:
:members: BaseMap, Layer, QueryLayer

Map Styling Functions
---------------------
Expand All @@ -43,3 +48,5 @@ Indices and tables
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

:Version: |version|
6 changes: 5 additions & 1 deletion docs/_static/basic.css
Expand Up @@ -445,10 +445,14 @@ dd {
margin-left: 30px;
}

dt:target, .highlighted {
dt:target, span.highlighted {
background-color: #fbe54e;
}

rect.highlighted {
fill: #fbe54e;
}

dl.glossary dt {
font-weight: bold;
font-size: 1.1em;
Expand Down
52 changes: 38 additions & 14 deletions docs/_static/doctools.js
Expand Up @@ -45,7 +45,7 @@ jQuery.urlencode = encodeURIComponent;
* it will always return arrays of strings for the value parts.
*/
jQuery.getQueryParameters = function(s) {
if (typeof s == 'undefined')
if (typeof s === 'undefined')
s = document.location.search;
var parts = s.substr(s.indexOf('?') + 1).split('&');
var result = {};
Expand All @@ -66,29 +66,53 @@ jQuery.getQueryParameters = function(s) {
* span elements with the given class name.
*/
jQuery.fn.highlightText = function(text, className) {
function highlight(node) {
if (node.nodeType == 3) {
function highlight(node, addItems) {
if (node.nodeType === 3) {
var val = node.nodeValue;
var pos = val.toLowerCase().indexOf(text);
if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) {
var span = document.createElement("span");
span.className = className;
var span;
var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg");
if (isInSVG) {
span = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
} else {
span = document.createElement("span");
span.className = className;
}
span.appendChild(document.createTextNode(val.substr(pos, text.length)));
node.parentNode.insertBefore(span, node.parentNode.insertBefore(
document.createTextNode(val.substr(pos + text.length)),
node.nextSibling));
node.nodeValue = val.substr(0, pos);
if (isInSVG) {
var bbox = span.getBBox();
var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
rect.x.baseVal.value = bbox.x;
rect.y.baseVal.value = bbox.y;
rect.width.baseVal.value = bbox.width;
rect.height.baseVal.value = bbox.height;
rect.setAttribute('class', className);
var parentOfText = node.parentNode.parentNode;
addItems.push({
"parent": node.parentNode,
"target": rect});
}
}
}
else if (!jQuery(node).is("button, select, textarea")) {
jQuery.each(node.childNodes, function() {
highlight(this);
highlight(this, addItems);
});
}
}
return this.each(function() {
highlight(this);
var addItems = [];
var result = this.each(function() {
highlight(this, addItems);
});
for (var i = 0; i < addItems.length; ++i) {
jQuery(addItems[i].parent).before(addItems[i].target);
}
return result;
};

/*
Expand Down Expand Up @@ -131,21 +155,21 @@ var Documentation = {
* i18n support
*/
TRANSLATIONS : {},
PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; },
PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; },
LOCALE : 'unknown',

// gettext and ngettext don't access this so that the functions
// can safely bound to a different name (_ = Documentation.gettext)
gettext : function(string) {
var translated = Documentation.TRANSLATIONS[string];
if (typeof translated == 'undefined')
if (typeof translated === 'undefined')
return string;
return (typeof translated == 'string') ? translated : translated[0];
return (typeof translated === 'string') ? translated : translated[0];
},

ngettext : function(singular, plural, n) {
var translated = Documentation.TRANSLATIONS[singular];
if (typeof translated == 'undefined')
if (typeof translated === 'undefined')
return (n == 1) ? singular : plural;
return translated[Documentation.PLURALEXPR(n)];
},
Expand Down Expand Up @@ -216,7 +240,7 @@ var Documentation = {
var src = $(this).attr('src');
var idnum = $(this).attr('id').substr(7);
$('tr.cg-' + idnum).toggle();
if (src.substr(-9) == 'minus.png')
if (src.substr(-9) === 'minus.png')
$(this).attr('src', src.substr(0, src.length-9) + 'plus.png');
else
$(this).attr('src', src.substr(0, src.length-8) + 'minus.png');
Expand Down Expand Up @@ -248,7 +272,7 @@ var Documentation = {
var path = document.location.pathname;
var parts = path.split(/\//);
$.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() {
if (this == '..')
if (this === '..')
parts.pop();
});
var url = parts.join('/');
Expand Down
3 changes: 3 additions & 0 deletions docs/_static/searchtools.js
Expand Up @@ -540,6 +540,9 @@ var Search = {
});
} else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {
var suffix = DOCUMENTATION_OPTIONS.SOURCELINK_SUFFIX;
if (suffix === undefined) {
suffix = '.txt';
}
$.ajax({url: DOCUMENTATION_OPTIONS.URL_ROOT + '_sources/' + item[5] + (item[5].slice(-suffix.length) === suffix ? '' : suffix),
dataType: "text",
complete: function(jqxhr, textstatus) {
Expand Down

0 comments on commit 0027393

Please sign in to comment.