[
  {
    "path": ".gitignore",
    "content": "*.pyc\nbuild\ndist\n.cache\n*.egg-info\n"
  },
  {
    "path": ".travis.yml",
    "content": "# Validate this file using http://lint.travis-ci.org/\nlanguage: python\nsudo: false\ncache: pip\npython:\n  - \"2.7\"\n  - \"3.4\"\n  - \"3.5\"\ninstall:\n  - pip install -r tests/requirements.txt -r doc/requirements.txt\n  - python setup.py install\nscript:\n  - py.test --mpl\n  - pushd doc && make html && popd\ndeploy:\n  provider: pypi\n  distributions: \"sdist bdist_wheel --universal\"\n  docs_dir: doc/.build/html\n  user: martijnvermaat\n  password:\n    secure: hPSuyetI+FkAzGkDnMlGJBvlDXfZS48y6onsH3cEcl3GN++3R3UsvNYywbJvCty38H3Odg5hjVaDUwxO4ozd0IvaGj/E2KkYrLAUrCeq4VSIp4HCr9jUXwIOWcfJY5gfq7t+xr68LmOlxinc9NOwLwePC49SOdE7Nj4VK8/ajnmUc9/1hlCVsddqs3I8T+soOamhNiJMwe+rDyEY6GI9dANibGxsJYKF5pa9mp1xE/eY4nUMVzXj28mijBIGeZkwzYNEcMvylOXwHu8lb/33JPVympld0s+qTL30Bjww72SlDtkLJwexYhBFCdZ+oPrV8xT8c4czWPwTgstWPAEwsCEW6m5rVwC0/jxclUMYM4CHIvUMUYSDjs4y0JjDo86LyfZqn3Dtiov40NHZbnE3zZvg3uICCxtQB1bbCjgM7QGbiUNK90OdSQU2JFKpWpbtK+c4JR9GlFrQfAOi4dIPEe2Bncws+uA+WbIKDSTm6XvEwiZYckEH6tPQ9v1/Drk28zMygRO9/ydCmtPBT7p6TXJGboPAztIPHs04dLSOl7tdfKp6SqjjBb3beBWTGEqz9unNf92WMIw76nvZC790XzLc7NXuo02JDFwuZIoFAvWbxo56sr0VW2NfPENAuv+vE8AF3jPb5xjOfzqoOPiEP7xlZ8mUm8/idz55ykKz2sU=\n  skip_cleanup: true\n  on:\n    tags: true\n    python: \"2.7\"\n"
  },
  {
    "path": "AUTHORS.rst",
    "content": "Calmap is written and maintained by Martijn Vermaat.\n\n- Martijn Vermaat <martijn@vermaat.name>\n"
  },
  {
    "path": "LICENSE.rst",
    "content": "Copyright (c) 2015 by Martijn Vermaat and contributors (see AUTHORS.rst\nfor details).\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "MANIFEST.in",
    "content": "include AUTHORS.rst CHANGES.rst LICENSE.rst README.rst\n"
  },
  {
    "path": "README.rst",
    "content": "| **Note:** See `MarvinT/calmap <https://github.com/MarvinT/calmap/>`_ for the maintained version of the project. That is also the version that gets published to PyPI and it has received several fixes to issues.\n\nCalendar heatmaps from Pandas time series data\n==============================================\n\nPlot `Pandas <http://pandas.pydata.org/>`_ time series data sampled by day in\na heatmap per calendar year, similar to GitHub's contributions plot, using\n`matplotlib <http://matplotlib.org/>`_.\n\n.. image:: https://pythonhosted.org/calmap/_images/index-2.png\n    :alt: Example calendar heatmap\n\n\nUsage\n-----\n\nSee the `documentation <https://pythonhosted.org/calmap>`_.\n\n\nInstallation\n------------\n\nTo install the latest release via PyPI using pip::\n\n    pip install calmap\n"
  },
  {
    "path": "calmap/__init__.py",
    "content": "\"\"\"\nCalendar heatmaps from Pandas time series data.\n\nPlot Pandas time series data sampled by day in a heatmap per calendar year,\nsimilar to GitHub's contributions calendar.\n\"\"\"\n\n\nfrom __future__ import unicode_literals\n\nimport calendar\nimport datetime\n\nfrom matplotlib.colors import ColorConverter, ListedColormap\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport pandas as pd\nfrom distutils.version import StrictVersion\n\n__version_info__ = ('0', '0', '7', 'dev')\n__date__ = '14 Feb 2016'\n\n\n__version__ = '.'.join(__version_info__)\n__author__ = 'Martijn Vermaat'\n__contact__ = 'martijn@vermaat.name'\n__homepage__ = 'https://github.com/martijnvermaat/calmap'\n\n_pandas_18 = StrictVersion(pd.__version__) >= StrictVersion('0.18')\n\n\ndef yearplot(data, year=None, how='sum', vmin=None, vmax=None, cmap='Reds',\n             fillcolor='whitesmoke', linewidth=1, linecolor=None,\n             daylabels=calendar.day_abbr[:], dayticks=True,\n             monthlabels=calendar.month_abbr[1:], monthticks=True, ax=None,\n             **kwargs):\n    \"\"\"\n    Plot one year from a timeseries as a calendar heatmap.\n\n    Parameters\n    ----------\n    data : Series\n        Data for the plot. Must be indexed by a DatetimeIndex.\n    year : integer\n        Only data indexed by this year will be plotted. If `None`, the first\n        year for which there is data will be plotted.\n    how : string\n        Method for resampling data by day. If `None`, assume data is already\n        sampled by day and don't resample. Otherwise, this is passed to Pandas\n        `Series.resample`.\n    vmin, vmax : floats\n        Values to anchor the colormap. If `None`, min and max are used after\n        resampling data by day.\n    cmap : matplotlib colormap name or object\n        The mapping from data values to color space.\n    fillcolor : matplotlib color\n        Color to use for days without data.\n    linewidth : float\n        Width of the lines that will divide each day.\n    linecolor : color\n        Color of the lines that will divide each day. If `None`, the axes\n        background color is used, or 'white' if it is transparent.\n    daylabels : list\n        Strings to use as labels for days, must be of length 7.\n    dayticks : list or int or bool\n        If `True`, label all days. If `False`, don't label days. If a list,\n        only label days with these indices. If an integer, label every n day.\n    monthlabels : list\n        Strings to use as labels for months, must be of length 12.\n    monthticks : list or int or bool\n        If `True`, label all months. If `False`, don't label months. If a\n        list, only label months with these indices. If an integer, label every\n        n month.\n    ax : matplotlib Axes\n        Axes in which to draw the plot, otherwise use the currently-active\n        Axes.\n    kwargs : other keyword arguments\n        All other keyword arguments are passed to matplotlib `ax.pcolormesh`.\n\n    Returns\n    -------\n    ax : matplotlib Axes\n        Axes object with the calendar heatmap.\n\n    Examples\n    --------\n\n    By default, `yearplot` plots the first year and sums the values per day:\n\n    .. plot::\n        :context: close-figs\n\n        calmap.yearplot(events)\n\n    We can choose which year is plotted with the `year` keyword argment:\n\n    .. plot::\n        :context: close-figs\n\n        calmap.yearplot(events, year=2015)\n\n    The appearance can be changed by using another colormap. Here we also use\n    a darker fill color for days without data and remove the lines:\n\n    .. plot::\n        :context: close-figs\n\n        calmap.yearplot(events, cmap='YlGn', fillcolor='grey',\n                        linewidth=0)\n\n    The axis tick labels can look a bit crowded. We can ask to draw only every\n    nth label, or explicitely supply the label indices. The labels themselves\n    can also be customized:\n\n    .. plot::\n        :context: close-figs\n\n        calmap.yearplot(events, monthticks=3, daylabels='MTWTFSS',\n                        dayticks=[0, 2, 4, 6])\n\n    \"\"\"\n    if year is None:\n        year = data.index.sort_values()[0].year\n\n    if how is None:\n        # Assume already sampled by day.\n        by_day = data\n    else:\n        # Sample by day.\n        if _pandas_18:\n            by_day = data.resample('D').agg(how)\n        else:\n            by_day = data.resample('D', how=how)\n\n    # Min and max per day.\n    if vmin is None:\n        vmin = by_day.min()\n    if vmax is None:\n        vmax = by_day.max()\n\n    if ax is None:\n        ax = plt.gca()\n\n    if linecolor is None:\n        # Unfortunately, linecolor cannot be transparent, as it is drawn on\n        # top of the heatmap cells. Therefore it is only possible to mimic\n        # transparent lines by setting them to the axes background color. This\n        # of course won't work when the axes itself has a transparent\n        # background so in that case we default to white which will usually be\n        # the figure or canvas background color.\n        linecolor = ax.get_fc()\n        # By: Ryan Susman - \"ax.get_axis_bgcolor()\" is deprecated, see:\n        # https://matplotlib.org/2.1.2/api/_as_gen/matplotlib.axes.Axes.get_axis_bgcolor.html\n        if ColorConverter().to_rgba(linecolor)[-1] == 0:\n            linecolor = 'white'\n\n    # Filter on year.\n    by_day = by_day[str(year)]\n\n    # Add missing days.\n    by_day = by_day.reindex(\n        pd.date_range(start=str(year), end=str(year + 1), freq='D')[:-1])\n\n    # Create data frame we can pivot later.\n    by_day = pd.DataFrame({'data': by_day,\n                           'fill': 1,\n                           'day': by_day.index.dayofweek,\n                           'week': by_day.index.week})\n\n    # There may be some days assigned to previous year's last week or\n    # next year's first week. We create new week numbers for them so\n    # the ordering stays intact and week/day pairs unique.\n    by_day.loc[(by_day.index.month == 1) & (by_day.week > 50), 'week'] = 0\n    by_day.loc[(by_day.index.month == 12) & (by_day.week < 10), 'week'] \\\n        = by_day.week.max() + 1\n\n    # Pivot data on day and week and mask NaN days.\n    plot_data = by_day.pivot('day', 'week', 'data').values[::-1]\n    plot_data = np.ma.masked_where(np.isnan(plot_data), plot_data)\n\n    # Do the same for all days of the year, not just those we have data for.\n    fill_data = by_day.pivot('day', 'week', 'fill').values[::-1]\n    fill_data = np.ma.masked_where(np.isnan(fill_data), fill_data)\n\n    # Draw heatmap for all days of the year with fill color.\n    ax.pcolormesh(fill_data, vmin=0, vmax=1, cmap=ListedColormap([fillcolor]))\n\n    # Draw heatmap.\n    kwargs['linewidth'] = linewidth\n    kwargs['edgecolors'] = linecolor\n    ax.pcolormesh(plot_data, vmin=vmin, vmax=vmax, cmap=cmap, **kwargs)\n\n    # Limit heatmap to our data.\n    ax.set(xlim=(0, plot_data.shape[1]), ylim=(0, plot_data.shape[0]))\n\n    # Square cells.\n    ax.set_aspect('equal')\n\n    # Remove spines and ticks.\n    for side in ('top', 'right', 'left', 'bottom'):\n        ax.spines[side].set_visible(False)\n    ax.xaxis.set_tick_params(which='both', length=0)\n    ax.yaxis.set_tick_params(which='both', length=0)\n\n    # Get indices for monthlabels.\n    if monthticks is True:\n        monthticks = range(len(monthlabels))\n    elif monthticks is False:\n        monthticks = []\n    elif isinstance(monthticks, int):\n        monthticks = range(len(monthlabels))[monthticks // 2::monthticks]\n\n    # Get indices for daylabels.\n    if dayticks is True:\n        dayticks = range(len(daylabels))\n    elif dayticks is False:\n        dayticks = []\n    elif isinstance(dayticks, int):\n        dayticks = range(len(daylabels))[dayticks // 2::dayticks]\n\n    ax.set_xlabel('')\n    ax.set_xticks([by_day.loc[datetime.date(year, i + 1, 15).strftime(\"%Y-%m-%d\"), 'week']\n                   for i in monthticks])\n    # df.ix is deprecated see:\n    # https://pandas.pydata.org/pandas-docs/version/0.23/generated/pandas.DataFrame.ix.html\n    ax.set_xticklabels([monthlabels[i] for i in monthticks], ha='center')\n\n    ax.set_ylabel('')\n    ax.yaxis.set_ticks_position('right')\n    ax.set_yticks([6 - i + 0.5 for i in dayticks])\n    ax.set_yticklabels([daylabels[i] for i in dayticks], rotation='horizontal',\n                       va='center')\n\n    return ax\n\n\ndef calendarplot(data, how='sum', yearlabels=True, yearascending=True, yearlabel_kws=None,\n                 subplot_kws=None, gridspec_kws=None, fig_kws=None, **kwargs):\n    \"\"\"\n    Plot a timeseries as a calendar heatmap.\n\n    Parameters\n    ----------\n    data : Series\n        Data for the plot. Must be indexed by a DatetimeIndex.\n    how : string\n        Method for resampling data by day. If `None`, assume data is already\n        sampled by day and don't resample. Otherwise, this is passed to Pandas\n        `Series.resample`.\n    yearlabels : bool\n       Whether or not to draw the year for each subplot.\n    yearascending : bool\n       Sort the calendar in ascending or descending order.\n    yearlabel_kws : dict\n       Keyword arguments passed to the matplotlib `set_ylabel` call which is\n       used to draw the year for each subplot.\n    subplot_kws : dict\n        Keyword arguments passed to the matplotlib `add_subplot` call used to\n        create each subplot.\n    gridspec_kws : dict\n        Keyword arguments passed to the matplotlib `GridSpec` constructor used\n        to create the grid the subplots are placed on.\n    fig_kws : dict\n        Keyword arguments passed to the matplotlib `figure` call.\n    kwargs : other keyword arguments\n        All other keyword arguments are passed to `yearplot`.\n\n    Returns\n    -------\n    fig, axes : matplotlib Figure and Axes\n        Tuple where `fig` is the matplotlib Figure object `axes` is an array\n        of matplotlib Axes objects with the calendar heatmaps, one per year.\n\n    Examples\n    --------\n\n    With `calendarplot` we can plot several years in one figure:\n\n    .. plot::\n        :context: close-figs\n\n        calmap.calendarplot(events)\n\n    \"\"\"\n    yearlabel_kws = yearlabel_kws or {}\n    subplot_kws = subplot_kws or {}\n    gridspec_kws = gridspec_kws or {}\n    fig_kws = fig_kws or {}\n\n    years = np.unique(data.index.year)\n    if not yearascending:\n        years = years[::-1]\n\n    fig, axes = plt.subplots(nrows=len(years), ncols=1, squeeze=False,\n                             subplot_kw=subplot_kws,\n                             gridspec_kw=gridspec_kws, **fig_kws)\n    axes = axes.T[0]\n\n    # We explicitely resample by day only once. This is an optimization.\n    if how is None:\n        by_day = data\n    else:\n        if _pandas_18:\n            by_day = data.resample('D').agg(how)\n        else:\n            by_day = data.resample('D', how=how)\n\n    ylabel_kws = dict(\n        fontsize=32,\n        color=kwargs.get('fillcolor', 'whitesmoke'),\n        fontweight='bold',\n        fontname='Arial',\n        ha='center')\n    ylabel_kws.update(yearlabel_kws)\n\n    max_weeks = 0\n\n    for year, ax in zip(years, axes):\n        yearplot(by_day, year=year, how=None, ax=ax, **kwargs)\n        max_weeks = max(max_weeks, ax.get_xlim()[1])\n\n        if yearlabels:\n            ax.set_ylabel(str(year), **ylabel_kws)\n\n    # In a leap year it might happen that we have 54 weeks (e.g., 2012).\n    # Here we make sure the width is consistent over all years.\n    for ax in axes:\n        ax.set_xlim(0, max_weeks)\n\n    # Make the axes look good.\n    plt.tight_layout()\n\n    return fig, axes\n"
  },
  {
    "path": "doc/.gitignore",
    "content": ".build\n"
  },
  {
    "path": "doc/Makefile",
    "content": "# Makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line.\nSPHINXOPTS    =\nSPHINXBUILD   = sphinx-build\nPAPER         =\nBUILDDIR      = .build\n\n# User-friendly check for sphinx-build\nifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)\n$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)\nendif\n\n# Internal variables.\nPAPEROPT_a4     = -D latex_paper_size=a4\nPAPEROPT_letter = -D latex_paper_size=letter\nALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .\n# the i18n builder cannot share the environment and doctrees with the others\nI18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .\n\n.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext\n\nhelp:\n\t@echo \"Please use \\`make <target>' where <target> is one of\"\n\t@echo \"  html       to make standalone HTML files\"\n\t@echo \"  dirhtml    to make HTML files named index.html in directories\"\n\t@echo \"  singlehtml to make a single large HTML file\"\n\t@echo \"  pickle     to make pickle files\"\n\t@echo \"  json       to make JSON files\"\n\t@echo \"  htmlhelp   to make HTML files and a HTML help project\"\n\t@echo \"  qthelp     to make HTML files and a qthelp project\"\n\t@echo \"  applehelp  to make an Apple Help Book\"\n\t@echo \"  devhelp    to make HTML files and a Devhelp project\"\n\t@echo \"  epub       to make an epub\"\n\t@echo \"  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter\"\n\t@echo \"  latexpdf   to make LaTeX files and run them through pdflatex\"\n\t@echo \"  latexpdfja to make LaTeX files and run them through platex/dvipdfmx\"\n\t@echo \"  text       to make text files\"\n\t@echo \"  man        to make manual pages\"\n\t@echo \"  texinfo    to make Texinfo files\"\n\t@echo \"  info       to make Texinfo files and run them through makeinfo\"\n\t@echo \"  gettext    to make PO message catalogs\"\n\t@echo \"  changes    to make an overview of all changed/added/deprecated items\"\n\t@echo \"  xml        to make Docutils-native XML files\"\n\t@echo \"  pseudoxml  to make pseudoxml-XML files for display purposes\"\n\t@echo \"  linkcheck  to check all external links for integrity\"\n\t@echo \"  doctest    to run all doctests embedded in the documentation (if enabled)\"\n\t@echo \"  coverage   to run coverage check of the documentation (if enabled)\"\n\nclean:\n\trm -rf $(BUILDDIR)/*\n\nhtml:\n\t$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html\n\t@echo\n\t@echo \"Build finished. The HTML pages are in $(BUILDDIR)/html.\"\n\ndirhtml:\n\t$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml\n\t@echo\n\t@echo \"Build finished. The HTML pages are in $(BUILDDIR)/dirhtml.\"\n\nsinglehtml:\n\t$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml\n\t@echo\n\t@echo \"Build finished. The HTML page is in $(BUILDDIR)/singlehtml.\"\n\npickle:\n\t$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle\n\t@echo\n\t@echo \"Build finished; now you can process the pickle files.\"\n\njson:\n\t$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json\n\t@echo\n\t@echo \"Build finished; now you can process the JSON files.\"\n\nhtmlhelp:\n\t$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp\n\t@echo\n\t@echo \"Build finished; now you can run HTML Help Workshop with the\" \\\n\t      \".hhp project file in $(BUILDDIR)/htmlhelp.\"\n\nqthelp:\n\t$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp\n\t@echo\n\t@echo \"Build finished; now you can run \"qcollectiongenerator\" with the\" \\\n\t      \".qhcp project file in $(BUILDDIR)/qthelp, like this:\"\n\t@echo \"# qcollectiongenerator $(BUILDDIR)/qthelp/Calmap.qhcp\"\n\t@echo \"To view the help file:\"\n\t@echo \"# assistant -collectionFile $(BUILDDIR)/qthelp/Calmap.qhc\"\n\napplehelp:\n\t$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp\n\t@echo\n\t@echo \"Build finished. The help book is in $(BUILDDIR)/applehelp.\"\n\t@echo \"N.B. You won't be able to view it unless you put it in\" \\\n\t      \"~/Library/Documentation/Help or install it in your application\" \\\n\t      \"bundle.\"\n\ndevhelp:\n\t$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp\n\t@echo\n\t@echo \"Build finished.\"\n\t@echo \"To view the help file:\"\n\t@echo \"# mkdir -p $$HOME/.local/share/devhelp/Calmap\"\n\t@echo \"# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Calmap\"\n\t@echo \"# devhelp\"\n\nepub:\n\t$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub\n\t@echo\n\t@echo \"Build finished. The epub file is in $(BUILDDIR)/epub.\"\n\nlatex:\n\t$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex\n\t@echo\n\t@echo \"Build finished; the LaTeX files are in $(BUILDDIR)/latex.\"\n\t@echo \"Run \\`make' in that directory to run these through (pdf)latex\" \\\n\t      \"(use \\`make latexpdf' here to do that automatically).\"\n\nlatexpdf:\n\t$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex\n\t@echo \"Running LaTeX files through pdflatex...\"\n\t$(MAKE) -C $(BUILDDIR)/latex all-pdf\n\t@echo \"pdflatex finished; the PDF files are in $(BUILDDIR)/latex.\"\n\nlatexpdfja:\n\t$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex\n\t@echo \"Running LaTeX files through platex and dvipdfmx...\"\n\t$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja\n\t@echo \"pdflatex finished; the PDF files are in $(BUILDDIR)/latex.\"\n\ntext:\n\t$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text\n\t@echo\n\t@echo \"Build finished. The text files are in $(BUILDDIR)/text.\"\n\nman:\n\t$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man\n\t@echo\n\t@echo \"Build finished. The manual pages are in $(BUILDDIR)/man.\"\n\ntexinfo:\n\t$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo\n\t@echo\n\t@echo \"Build finished. The Texinfo files are in $(BUILDDIR)/texinfo.\"\n\t@echo \"Run \\`make' in that directory to run these through makeinfo\" \\\n\t      \"(use \\`make info' here to do that automatically).\"\n\ninfo:\n\t$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo\n\t@echo \"Running Texinfo files through makeinfo...\"\n\tmake -C $(BUILDDIR)/texinfo info\n\t@echo \"makeinfo finished; the Info files are in $(BUILDDIR)/texinfo.\"\n\ngettext:\n\t$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale\n\t@echo\n\t@echo \"Build finished. The message catalogs are in $(BUILDDIR)/locale.\"\n\nchanges:\n\t$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes\n\t@echo\n\t@echo \"The overview file is in $(BUILDDIR)/changes.\"\n\nlinkcheck:\n\t$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck\n\t@echo\n\t@echo \"Link check complete; look for any errors in the above output \" \\\n\t      \"or in $(BUILDDIR)/linkcheck/output.txt.\"\n\ndoctest:\n\t$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest\n\t@echo \"Testing of doctests in the sources finished, look at the \" \\\n\t      \"results in $(BUILDDIR)/doctest/output.txt.\"\n\ncoverage:\n\t$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage\n\t@echo \"Testing of coverage in the sources finished, look at the \" \\\n\t      \"results in $(BUILDDIR)/coverage/python.txt.\"\n\nxml:\n\t$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml\n\t@echo\n\t@echo \"Build finished. The XML files are in $(BUILDDIR)/xml.\"\n\npseudoxml:\n\t$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml\n\t@echo\n\t@echo \"Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml.\"\n"
  },
  {
    "path": "doc/conf.py",
    "content": "# -*- coding: utf-8 -*-\n#\n# Calmap documentation build configuration file, created by\n# sphinx-quickstart on Thu Nov 26 16:51:51 2015.\n#\n# This file is execfile()d with the current directory set to its\n# containing dir.\n#\n# Note that not all possible configuration values are present in this\n# autogenerated file.\n#\n# All configuration values have a default; values that are commented out\n# serve to show the default.\n\nimport sys\nimport os\nimport matplotlib as mpl\nmpl.use('Agg')\n\n# If extensions (or modules to document with autodoc) are in another directory,\n# add these directories to sys.path here. If the directory is relative to the\n# documentation root, use os.path.abspath to make it absolute, like shown here.\nsys.path.insert(0, os.path.abspath('..'))\n\n# -- General configuration ------------------------------------------------\nimport calmap\n\n# If your documentation needs a minimal Sphinx version, state it here.\n#needs_sphinx = '1.0'\n\n# Add any Sphinx extension module names here, as strings. They can be\n# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom\n# ones.\n# The plot_directive extension is a modification of the one bundled with\n# matplotlib, adding a fig.tight_layout() call and setting bbox_inches\n# to 'tight' on the savefig call.\nsys.path.insert(0, os.path.abspath('sphinxext'))\nextensions = [\n    'plot_directive',\n    'sphinx.ext.autodoc',\n    'sphinx.ext.viewcode',\n    'numpydoc'\n]\n\n# Configuration for plot_directive.\nplot_include_source = True\nplot_formats = [(\"png\", 90)]\nplot_html_show_formats = False\nplot_html_show_source_link = False\n\n# Add any paths that contain templates here, relative to this directory.\ntemplates_path = ['.templates']\n\n# The suffix(es) of source filenames.\n# You can specify multiple suffix as a list of string:\n# source_suffix = ['.rst', '.md']\nsource_suffix = '.rst'\n\n# The encoding of source files.\n#source_encoding = 'utf-8-sig'\n\n# The master toctree document.\nmaster_doc = 'index'\n\n# General information about the project.\nproject = u'Calmap'\ncopyright = u'2015, %s' % calmap.__author__\nauthor = calmap.__author__\n\n# The version info for the project you're documenting, acts as replacement for\n# |version| and |release|, also used in various other places throughout the\n# built documents.\n#\n# The short X.Y version.\nversion = '.'.join(calmap.__version__.split('.')[:2])\n# The full version, including alpha/beta/rc tags.\nrelease = calmap.__version__\n\n# The language for content autogenerated by Sphinx. Refer to documentation\n# for a list of supported languages.\n#\n# This is also used if you do content translation via gettext catalogs.\n# Usually you set \"language\" from the command line for these cases.\nlanguage = None\n\n# There are two options for replacing |today|: either, you set today to some\n# non-false value, then it is used:\n#today = ''\n# Else, today_fmt is used as the format for a strftime call.\n#today_fmt = '%B %d, %Y'\n\n# List of patterns, relative to source directory, that match files and\n# directories to ignore when looking for source files.\nexclude_patterns = ['.build']\n\n# The reST default role (used for this markup: `text`) to use for all\n# documents.\n#default_role = None\n\n# If true, '()' will be appended to :func: etc. cross-reference text.\n#add_function_parentheses = True\n\n# If true, the current module name will be prepended to all description\n# unit titles (such as .. function::).\n#add_module_names = True\n\n# If true, sectionauthor and moduleauthor directives will be shown in the\n# output. They are ignored by default.\n#show_authors = False\n\n# The name of the Pygments (syntax highlighting) style to use.\npygments_style = 'sphinx'\n\n# A list of ignored prefixes for module index sorting.\n#modindex_common_prefix = []\n\n# If true, keep warnings as \"system message\" paragraphs in the built documents.\n#keep_warnings = False\n\n# If true, `todo` and `todoList` produce output, else they produce nothing.\ntodo_include_todos = False\n\n\n# -- Options for HTML output ----------------------------------------------\n\n# The theme to use for HTML and HTML Help pages.  See the documentation for\n# a list of builtin themes.\nhtml_theme = 'alabaster'\n\n# Theme options are theme-specific and customize the look and feel of a theme\n# further.  For a list of options available for each theme, see the\n# documentation.\nhtml_theme_options = {\n    'github_banner': True,\n    'github_user': 'martijnvermaat',\n    'github_repo': 'calmap'\n}\n\n# Add any paths that contain custom themes here, relative to this directory.\n#html_theme_path = []\n\n# The name for this set of Sphinx documents.  If None, it defaults to\n# \"<project> v<release> documentation\".\n#html_title = None\n\n# A shorter title for the navigation bar.  Default is the same as html_title.\n#html_short_title = None\n\n# The name of an image file (relative to this directory) to place at the top\n# of the sidebar.\n#html_logo = None\n\n# The name of an image file (within the static path) to use as favicon of the\n# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32\n# pixels large.\n#html_favicon = None\n\n# Add any paths that contain custom static files (such as style sheets) here,\n# relative to this directory. They are copied after the builtin static files,\n# so a file named \"default.css\" will overwrite the builtin \"default.css\".\nhtml_static_path = ['.static']\n\n# Add any extra paths that contain custom files (such as robots.txt or\n# .htaccess) here, relative to this directory. These files are copied\n# directly to the root of the documentation.\n#html_extra_path = []\n\n# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,\n# using the given strftime format.\n#html_last_updated_fmt = '%b %d, %Y'\n\n# If true, SmartyPants will be used to convert quotes and dashes to\n# typographically correct entities.\n#html_use_smartypants = True\n\n# Custom sidebar templates, maps document names to template names.\n#html_sidebars = {}\n\n# Additional templates that should be rendered to pages, maps page names to\n# template names.\n#html_additional_pages = {}\n\n# If false, no module index is generated.\n#html_domain_indices = True\n\n# If false, no index is generated.\n#html_use_index = True\n\n# If true, the index is split into individual pages for each letter.\n#html_split_index = False\n\n# If true, links to the reST sources are added to the pages.\n#html_show_sourcelink = True\n\n# If true, \"Created using Sphinx\" is shown in the HTML footer. Default is True.\n#html_show_sphinx = True\n\n# If true, \"(C) Copyright ...\" is shown in the HTML footer. Default is True.\n#html_show_copyright = True\n\n# If true, an OpenSearch description file will be output, and all pages will\n# contain a <link> tag referring to it.  The value of this option must be the\n# base URL from which the finished HTML is served.\n#html_use_opensearch = ''\n\n# This is the file name suffix for HTML files (e.g. \".xhtml\").\n#html_file_suffix = None\n\n# Language to be used for generating the HTML full-text search index.\n# Sphinx supports the following languages:\n#   'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'\n#   'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr'\n#html_search_language = 'en'\n\n# A dictionary with options for the search language support, empty by default.\n# Now only 'ja' uses this config value\n#html_search_options = {'type': 'default'}\n\n# The name of a javascript file (relative to the configuration directory) that\n# implements a search results scorer. If empty, the default will be used.\n#html_search_scorer = 'scorer.js'\n\n# Output file base name for HTML help builder.\nhtmlhelp_basename = 'Calmapdoc'\n\n# -- Options for LaTeX output ---------------------------------------------\n\nlatex_elements = {\n# The paper size ('letterpaper' or 'a4paper').\n#'papersize': 'letterpaper',\n\n# The font size ('10pt', '11pt' or '12pt').\n#'pointsize': '10pt',\n\n# Additional stuff for the LaTeX preamble.\n#'preamble': '',\n\n# Latex figure (float) alignment\n#'figure_align': 'htbp',\n}\n\n# Grouping the document tree into LaTeX files. List of tuples\n# (source start file, target name, title,\n#  author, documentclass [howto, manual, or own class]).\nlatex_documents = [\n  (master_doc, 'Calmap.tex', u'Calmap Documentation',\n   u'Martijn Vermaat', 'manual'),\n]\n\n# The name of an image file (relative to this directory) to place at the top of\n# the title page.\n#latex_logo = None\n\n# For \"manual\" documents, if this is true, then toplevel headings are parts,\n# not chapters.\n#latex_use_parts = False\n\n# If true, show page references after internal links.\n#latex_show_pagerefs = False\n\n# If true, show URL addresses after external links.\n#latex_show_urls = False\n\n# Documents to append as an appendix to all manuals.\n#latex_appendices = []\n\n# If false, no module index is generated.\n#latex_domain_indices = True\n\n\n# -- Options for manual page output ---------------------------------------\n\n# One entry per manual page. List of tuples\n# (source start file, name, description, authors, manual section).\nman_pages = [\n    (master_doc, 'calmap', u'Calmap Documentation',\n     [author], 1)\n]\n\n# If true, show URL addresses after external links.\n#man_show_urls = False\n\n\n# -- Options for Texinfo output -------------------------------------------\n\n# Grouping the document tree into Texinfo files. List of tuples\n# (source start file, target name, title, author,\n#  dir menu entry, description, category)\ntexinfo_documents = [\n  (master_doc, 'Calmap', u'Calmap Documentation',\n   author, 'Calmap', 'One line description of project.',\n   'Miscellaneous'),\n]\n\n# Documents to append as an appendix to all manuals.\n#texinfo_appendices = []\n\n# If false, no module index is generated.\n#texinfo_domain_indices = True\n\n# How to display URL addresses: 'footnote', 'no', or 'inline'.\n#texinfo_show_urls = 'footnote'\n\n# If true, do not generate a @detailmenu in the \"Top\" node's menu.\n#texinfo_no_detailmenu = False\n"
  },
  {
    "path": "doc/index.rst",
    "content": ".. currentmodule:: calmap\n\n\nCalendar heatmaps from Pandas time series data\n==============================================\n\nPlot `Pandas <http://pandas.pydata.org/>`_ time series data sampled by day in\na heatmap per calendar year, similar to GitHub's contributions plot, using\n`matplotlib <http://matplotlib.org/>`_.\n\n\nUsage\n-----\n\nAssume we have some weighted events as a Pandas Series with a\nDatetimeIndex. They could be Git commits (with the diff size as weight),\nmileage of your runs, or minutes spent on telemarketing phone calls driving\nyou crazy.\n\nFor illustration purposes we just create 500 events as random float values\nassigned to random days over a 700-day period:\n\n.. plot::\n    :context: close-figs\n\n    import numpy as np; np.random.seed(sum(map(ord, 'calmap')))\n    import pandas as pd\n    import calmap\n\n    all_days = pd.date_range('1/15/2014', periods=700, freq='D')\n    days = np.random.choice(all_days, 500)\n    events = pd.Series(np.random.randn(len(days)), index=days)\n\nUsing :func:`yearplot`, we can easily plot a heatmap of these events over a\nyear:\n\n.. plot::\n    :context: close-figs\n\n    calmap.yearplot(events, year=2015)\n\nOr we can use :func:`calendarplot` to plot all years as subplots into one\nfigure:\n\n.. plot::\n    :context: close-figs\n\n    calmap.calendarplot(events, monthticks=3, daylabels='MTWTFSS',\n                        dayticks=[0, 2, 4, 6], cmap='YlGn',\n                        fillcolor='grey', linewidth=0,\n                        fig_kws=dict(figsize=(8, 4)))\n\nSee the :ref:`API documentation <api>` for more information and examples.\n\n\nInstallation\n------------\n\nTo install the latest release via PyPI using pip::\n\n    pip install calmap\n\nThe latest development version `can be found on GitHub\n<https://github.com/martijnvermaat/calmap>`_.\n\n\n.. _api:\n\nAPI documentation\n-----------------\n\n.. module:: calmap\n\n.. autofunction:: yearplot\n.. autofunction:: calendarplot\n\n\nCopyright\n---------\n\nThis library is licensed under the MIT License, meaning you can do whatever\nyou want with it as long as all copies include these license terms. The full\nlicense text can be found in the LICENSE.rst file. See the AUTHORS.rst for for\na complete list of copyright holders.\n"
  },
  {
    "path": "doc/requirements.txt",
    "content": "matplotlib>=1.5.0\nnumpydoc\nSphinx\n"
  },
  {
    "path": "doc/sphinxext/plot_directive.py",
    "content": "\"\"\"\nA directive for including a matplotlib plot in a Sphinx document.\n\nBy default, in HTML output, `plot` will include a .png file with a\nlink to a high-res .png and .pdf.  In LaTeX output, it will include a\n.pdf.\n\nThe source code for the plot may be included in one of three ways:\n\n  1. **A path to a source file** as the argument to the directive::\n\n       .. plot:: path/to/plot.py\n\n     When a path to a source file is given, the content of the\n     directive may optionally contain a caption for the plot::\n\n       .. plot:: path/to/plot.py\n\n          This is the caption for the plot\n\n     Additionally, one may specify the name of a function to call (with\n     no arguments) immediately after importing the module::\n\n       .. plot:: path/to/plot.py plot_function1\n\n  2. Included as **inline content** to the directive::\n\n       .. plot::\n\n          import matplotlib.pyplot as plt\n          import matplotlib.image as mpimg\n          import numpy as np\n          img = mpimg.imread('_static/stinkbug.png')\n          imgplot = plt.imshow(img)\n\n  3. Using **doctest** syntax::\n\n       .. plot::\n          A plotting example:\n          >>> import matplotlib.pyplot as plt\n          >>> plt.plot([1,2,3], [4,5,6])\n\nOptions\n-------\n\nThe ``plot`` directive supports the following options:\n\n    format : {'python', 'doctest'}\n        Specify the format of the input\n\n    include-source : bool\n        Whether to display the source code. The default can be changed\n        using the `plot_include_source` variable in conf.py\n\n    encoding : str\n        If this source file is in a non-UTF8 or non-ASCII encoding,\n        the encoding must be specified using the `:encoding:` option.\n        The encoding will not be inferred using the ``-*- coding -*-``\n        metacomment.\n\n    context : bool or str\n        If provided, the code will be run in the context of all\n        previous plot directives for which the `:context:` option was\n        specified.  This only applies to inline code plot directives,\n        not those run from files. If the ``:context: reset`` option is\n        specified, the context is reset for this and future plots, and\n        previous figures are closed prior to running the code.\n        ``:context:close-figs`` keeps the context but closes previous figures\n        before running the code.\n\n    nofigs : bool\n        If specified, the code block will be run, but no figures will\n        be inserted.  This is usually useful with the ``:context:``\n        option.\n\nAdditionally, this directive supports all of the options of the\n`image` directive, except for `target` (since plot will add its own\ntarget).  These include `alt`, `height`, `width`, `scale`, `align` and\n`class`.\n\nConfiguration options\n---------------------\n\nThe plot directive has the following configuration options:\n\n    plot_include_source\n        Default value for the include-source option\n\n    plot_html_show_source_link\n        Whether to show a link to the source in HTML.\n\n    plot_pre_code\n        Code that should be executed before each plot.\n\n    plot_basedir\n        Base directory, to which ``plot::`` file names are relative\n        to.  (If None or empty, file names are relative to the\n        directory where the file containing the directive is.)\n\n    plot_formats\n        File formats to generate. List of tuples or strings::\n\n            [(suffix, dpi), suffix, ...]\n\n        that determine the file format and the DPI. For entries whose\n        DPI was omitted, sensible defaults are chosen. When passing from\n        the command line through sphinx_build the list should be passed as\n        suffix:dpi,suffix:dpi, ....\n\n    plot_html_show_formats\n        Whether to show links to the files in HTML.\n\n    plot_rcparams\n        A dictionary containing any non-standard rcParams that should\n        be applied before each plot.\n\n    plot_apply_rcparams\n        By default, rcParams are applied when `context` option is not used in\n        a plot directive.  This configuration option overrides this behavior\n        and applies rcParams before each plot.\n\n    plot_working_directory\n        By default, the working directory will be changed to the directory of\n        the example, so the code can get at its data files, if any.  Also its\n        path will be added to `sys.path` so it can import any helper modules\n        sitting beside it.  This configuration option can be used to specify\n        a central directory (also added to `sys.path`) where data files and\n        helper modules for all code are located.\n\n    plot_template\n        Provide a customized template for preparing restructured text.\n\"\"\"\nfrom __future__ import (absolute_import, division, print_function,\n                        unicode_literals)\n\nfrom matplotlib.externals import six\nfrom matplotlib.externals.six.moves import xrange\n\nimport sys, os, shutil, io, re, textwrap\nfrom os.path import relpath\nimport traceback\nimport warnings\n\nif not six.PY3:\n    import cStringIO\n\nfrom docutils.parsers.rst import directives\nfrom docutils.parsers.rst.directives.images import Image\nalign = Image.align\nimport sphinx\n\nsphinx_version = sphinx.__version__.split(\".\")\n# The split is necessary for sphinx beta versions where the string is\n# '6b1'\nsphinx_version = tuple([int(re.split('[^0-9]', x)[0])\n                        for x in sphinx_version[:2]])\n\ntry:\n    # Sphinx depends on either Jinja or Jinja2\n    import jinja2\n    def format_template(template, **kw):\n        return jinja2.Template(template).render(**kw)\nexcept ImportError:\n    import jinja\n    def format_template(template, **kw):\n        return jinja.from_string(template, **kw)\n\nimport matplotlib\nimport matplotlib.cbook as cbook\ntry:\n    with warnings.catch_warnings(record=True):\n        warnings.simplefilter(\"error\", UserWarning)\n        matplotlib.use('Agg')\nexcept UserWarning:\n    import matplotlib.pyplot as plt\n    plt.switch_backend(\"Agg\")\nelse:\n    import matplotlib.pyplot as plt\nfrom matplotlib import _pylab_helpers\n\n__version__ = 2\n\n#------------------------------------------------------------------------------\n# Registration hook\n#------------------------------------------------------------------------------\n\ndef plot_directive(name, arguments, options, content, lineno,\n                   content_offset, block_text, state, state_machine):\n    return run(arguments, content, options, state_machine, state, lineno)\nplot_directive.__doc__ = __doc__\n\n\ndef _option_boolean(arg):\n    if not arg or not arg.strip():\n        # no argument given, assume used as a flag\n        return True\n    elif arg.strip().lower() in ('no', '0', 'false'):\n        return False\n    elif arg.strip().lower() in ('yes', '1', 'true'):\n        return True\n    else:\n        raise ValueError('\"%s\" unknown boolean' % arg)\n\n\ndef _option_context(arg):\n    if arg in [None, 'reset', 'close-figs']:\n        return arg\n    raise ValueError(\"argument should be None or 'reset' or 'close-figs'\")\n\n\ndef _option_format(arg):\n    return directives.choice(arg, ('python', 'doctest'))\n\n\ndef _option_align(arg):\n    return directives.choice(arg, (\"top\", \"middle\", \"bottom\", \"left\", \"center\",\n                                   \"right\"))\n\n\ndef mark_plot_labels(app, document):\n    \"\"\"\n    To make plots referenceable, we need to move the reference from\n    the \"htmlonly\" (or \"latexonly\") node to the actual figure node\n    itself.\n    \"\"\"\n    for name, explicit in six.iteritems(document.nametypes):\n        if not explicit:\n            continue\n        labelid = document.nameids[name]\n        if labelid is None:\n            continue\n        node = document.ids[labelid]\n        if node.tagname in ('html_only', 'latex_only'):\n            for n in node:\n                if n.tagname == 'figure':\n                    sectname = name\n                    for c in n:\n                        if c.tagname == 'caption':\n                            sectname = c.astext()\n                            break\n\n                    node['ids'].remove(labelid)\n                    node['names'].remove(name)\n                    n['ids'].append(labelid)\n                    n['names'].append(name)\n                    document.settings.env.labels[name] = \\\n                        document.settings.env.docname, labelid, sectname\n                    break\n\n\ndef setup(app):\n    setup.app = app\n    setup.config = app.config\n    setup.confdir = app.confdir\n\n    options = {'alt': directives.unchanged,\n               'height': directives.length_or_unitless,\n               'width': directives.length_or_percentage_or_unitless,\n               'scale': directives.nonnegative_int,\n               'align': _option_align,\n               'class': directives.class_option,\n               'include-source': _option_boolean,\n               'format': _option_format,\n               'context': _option_context,\n               'nofigs': directives.flag,\n               'encoding': directives.encoding\n               }\n\n    app.add_directive('plot', plot_directive, True, (0, 2, False), **options)\n    app.add_config_value('plot_pre_code', None, True)\n    app.add_config_value('plot_include_source', False, True)\n    app.add_config_value('plot_html_show_source_link', True, True)\n    app.add_config_value('plot_formats', ['png', 'hires.png', 'pdf'], True)\n    app.add_config_value('plot_basedir', None, True)\n    app.add_config_value('plot_html_show_formats', True, True)\n    app.add_config_value('plot_rcparams', {}, True)\n    app.add_config_value('plot_apply_rcparams', False, True)\n    app.add_config_value('plot_working_directory', None, True)\n    app.add_config_value('plot_template', None, True)\n\n    app.connect(str('doctree-read'), mark_plot_labels)\n\n#------------------------------------------------------------------------------\n# Doctest handling\n#------------------------------------------------------------------------------\n\ndef contains_doctest(text):\n    try:\n        # check if it's valid Python as-is\n        compile(text, '<string>', 'exec')\n        return False\n    except SyntaxError:\n        pass\n    r = re.compile(r'^\\s*>>>', re.M)\n    m = r.search(text)\n    return bool(m)\n\n\ndef unescape_doctest(text):\n    \"\"\"\n    Extract code from a piece of text, which contains either Python code\n    or doctests.\n\n    \"\"\"\n    if not contains_doctest(text):\n        return text\n\n    code = \"\"\n    for line in text.split(\"\\n\"):\n        m = re.match(r'^\\s*(>>>|\\.\\.\\.) (.*)$', line)\n        if m:\n            code += m.group(2) + \"\\n\"\n        elif line.strip():\n            code += \"# \" + line.strip() + \"\\n\"\n        else:\n            code += \"\\n\"\n    return code\n\n\ndef split_code_at_show(text):\n    \"\"\"\n    Split code at plt.show()\n\n    \"\"\"\n\n    parts = []\n    is_doctest = contains_doctest(text)\n\n    part = []\n    for line in text.split(\"\\n\"):\n        if (not is_doctest and line.strip() == 'plt.show()') or \\\n               (is_doctest and line.strip() == '>>> plt.show()'):\n            part.append(line)\n            parts.append(\"\\n\".join(part))\n            part = []\n        else:\n            part.append(line)\n    if \"\\n\".join(part).strip():\n        parts.append(\"\\n\".join(part))\n    return parts\n\n\ndef remove_coding(text):\n    \"\"\"\n    Remove the coding comment, which six.exec_ doesn't like.\n    \"\"\"\n    sub_re = re.compile(\"^#\\s*-\\*-\\s*coding:\\s*.*-\\*-$\", flags=re.MULTILINE)\n    return sub_re.sub(\"\", text)\n\n#------------------------------------------------------------------------------\n# Template\n#------------------------------------------------------------------------------\n\n\nTEMPLATE = \"\"\"\n{{ source_code }}\n\n{{ only_html }}\n\n   {% if source_link or (html_show_formats and not multi_image) %}\n   (\n   {%- if source_link -%}\n   `Source code <{{ source_link }}>`__\n   {%- endif -%}\n   {%- if html_show_formats and not multi_image -%}\n     {%- for img in images -%}\n       {%- for fmt in img.formats -%}\n         {%- if source_link or not loop.first -%}, {% endif -%}\n         `{{ fmt }} <{{ dest_dir }}/{{ img.basename }}.{{ fmt }}>`__\n       {%- endfor -%}\n     {%- endfor -%}\n   {%- endif -%}\n   )\n   {% endif %}\n\n   {% for img in images %}\n   .. figure:: {{ build_dir }}/{{ img.basename }}.png\n      {% for option in options -%}\n      {{ option }}\n      {% endfor %}\n\n      {% if html_show_formats and multi_image -%}\n        (\n        {%- for fmt in img.formats -%}\n        {%- if not loop.first -%}, {% endif -%}\n        `{{ fmt }} <{{ dest_dir }}/{{ img.basename }}.{{ fmt }}>`__\n        {%- endfor -%}\n        )\n      {%- endif -%}\n\n      {{ caption }}\n   {% endfor %}\n\n{{ only_latex }}\n\n   {% for img in images %}\n   {% if 'pdf' in img.formats -%}\n   .. image:: {{ build_dir }}/{{ img.basename }}.pdf\n   {% endif -%}\n   {% endfor %}\n\n{{ only_texinfo }}\n\n   {% for img in images %}\n   .. image:: {{ build_dir }}/{{ img.basename }}.png\n      {% for option in options -%}\n      {{ option }}\n      {% endfor %}\n\n   {% endfor %}\n\n\"\"\"\n\nexception_template = \"\"\"\n.. htmlonly::\n\n   [`source code <%(linkdir)s/%(basename)s.py>`__]\n\nException occurred rendering plot.\n\n\"\"\"\n\n# the context of the plot for all directives specified with the\n# :context: option\nplot_context = dict()\n\nclass ImageFile(object):\n    def __init__(self, basename, dirname):\n        self.basename = basename\n        self.dirname = dirname\n        self.formats = []\n\n    def filename(self, format):\n        return os.path.join(self.dirname, \"%s.%s\" % (self.basename, format))\n\n    def filenames(self):\n        return [self.filename(fmt) for fmt in self.formats]\n\n\ndef out_of_date(original, derived):\n    \"\"\"\n    Returns True if derivative is out-of-date wrt original,\n    both of which are full file paths.\n    \"\"\"\n    return (not os.path.exists(derived) or\n            (os.path.exists(original) and\n             os.stat(derived).st_mtime < os.stat(original).st_mtime))\n\n\nclass PlotError(RuntimeError):\n    pass\n\n\ndef run_code(code, code_path, ns=None, function_name=None):\n    \"\"\"\n    Import a Python module from a path, and run the function given by\n    name, if function_name is not None.\n    \"\"\"\n\n    # Change the working directory to the directory of the example, so\n    # it can get at its data files, if any.  Add its path to sys.path\n    # so it can import any helper modules sitting beside it.\n    if six.PY2:\n        pwd = os.getcwdu()\n    else:\n        pwd = os.getcwd()\n    old_sys_path = list(sys.path)\n    if setup.config.plot_working_directory is not None:\n        try:\n            os.chdir(setup.config.plot_working_directory)\n        except OSError as err:\n            raise OSError(str(err) + '\\n`plot_working_directory` option in'\n                          'Sphinx configuration file must be a valid '\n                          'directory path')\n        except TypeError as err:\n            raise TypeError(str(err) + '\\n`plot_working_directory` option in '\n                            'Sphinx configuration file must be a string or '\n                            'None')\n        sys.path.insert(0, setup.config.plot_working_directory)\n    elif code_path is not None:\n        dirname = os.path.abspath(os.path.dirname(code_path))\n        os.chdir(dirname)\n        sys.path.insert(0, dirname)\n\n    # Reset sys.argv\n    old_sys_argv = sys.argv\n    sys.argv = [code_path]\n\n    # Redirect stdout\n    stdout = sys.stdout\n    if six.PY3:\n        sys.stdout = io.StringIO()\n    else:\n        sys.stdout = cStringIO.StringIO()\n\n    # Assign a do-nothing print function to the namespace.  There\n    # doesn't seem to be any other way to provide a way to (not) print\n    # that works correctly across Python 2 and 3.\n    def _dummy_print(*arg, **kwarg):\n        pass\n\n    try:\n        try:\n            code = unescape_doctest(code)\n            if ns is None:\n                ns = {}\n            if not ns:\n                if setup.config.plot_pre_code is None:\n                    six.exec_(six.text_type(\"import numpy as np\\n\" +\n                    \"from matplotlib import pyplot as plt\\n\"), ns)\n                else:\n                    six.exec_(six.text_type(setup.config.plot_pre_code), ns)\n            ns['print'] = _dummy_print\n            if \"__main__\" in code:\n                six.exec_(\"__name__ = '__main__'\", ns)\n            code = remove_coding(code)\n            six.exec_(code, ns)\n            if function_name is not None:\n                six.exec_(function_name + \"()\", ns)\n        except (Exception, SystemExit) as err:\n            raise PlotError(traceback.format_exc())\n    finally:\n        os.chdir(pwd)\n        sys.argv = old_sys_argv\n        sys.path[:] = old_sys_path\n        sys.stdout = stdout\n    return ns\n\n\ndef clear_state(plot_rcparams, close=True):\n    if close:\n        plt.close('all')\n    matplotlib.rc_file_defaults()\n    matplotlib.rcParams.update(plot_rcparams)\n\n\ndef render_figures(code, code_path, output_dir, output_base, context,\n                   function_name, config, context_reset=False,\n                   close_figs=False):\n    \"\"\"\n    Run a pyplot script and save the low and high res PNGs and a PDF\n    in *output_dir*.\n\n    Save the images under *output_dir* with file names derived from\n    *output_base*\n    \"\"\"\n    # -- Parse format list\n    default_dpi = {'png': 80, 'hires.png': 200, 'pdf': 200}\n    formats = []\n    plot_formats = config.plot_formats\n    if isinstance(plot_formats, six.string_types):\n        # String Sphinx < 1.3, Split on , to mimic\n        # Sphinx 1.3 and later. Sphinx 1.3 always\n        # returns a list.\n        plot_formats = plot_formats.split(',')\n    for fmt in plot_formats:\n        if isinstance(fmt, six.string_types):\n            if ':' in fmt:\n                suffix,dpi = fmt.split(':')\n                formats.append((str(suffix), int(dpi)))\n            else:\n                formats.append((fmt, default_dpi.get(fmt, 80)))\n        elif type(fmt) in (tuple, list) and len(fmt)==2:\n            formats.append((str(fmt[0]), int(fmt[1])))\n        else:\n            raise PlotError('invalid image format \"%r\" in plot_formats' % fmt)\n\n    # -- Try to determine if all images already exist\n\n    code_pieces = split_code_at_show(code)\n\n    # Look for single-figure output files first\n    all_exists = True\n    img = ImageFile(output_base, output_dir)\n    for format, dpi in formats:\n        if out_of_date(code_path, img.filename(format)):\n            all_exists = False\n            break\n        img.formats.append(format)\n\n    if all_exists:\n        return [(code, [img])]\n\n    # Then look for multi-figure output files\n    results = []\n    all_exists = True\n    for i, code_piece in enumerate(code_pieces):\n        images = []\n        for j in xrange(1000):\n            if len(code_pieces) > 1:\n                img = ImageFile('%s_%02d_%02d' % (output_base, i, j), output_dir)\n            else:\n                img = ImageFile('%s_%02d' % (output_base, j), output_dir)\n            for format, dpi in formats:\n                if out_of_date(code_path, img.filename(format)):\n                    all_exists = False\n                    break\n                img.formats.append(format)\n\n            # assume that if we have one, we have them all\n            if not all_exists:\n                all_exists = (j > 0)\n                break\n            images.append(img)\n        if not all_exists:\n            break\n        results.append((code_piece, images))\n\n    if all_exists:\n        return results\n\n    # We didn't find the files, so build them\n\n    results = []\n    if context:\n        ns = plot_context\n    else:\n        ns = {}\n\n    if context_reset:\n        clear_state(config.plot_rcparams)\n        plot_context.clear()\n\n    close_figs = not context or close_figs\n\n    for i, code_piece in enumerate(code_pieces):\n\n        if not context or config.plot_apply_rcparams:\n            clear_state(config.plot_rcparams, close_figs)\n        elif close_figs:\n            plt.close('all')\n\n        run_code(code_piece, code_path, ns, function_name)\n\n        images = []\n        fig_managers = _pylab_helpers.Gcf.get_all_fig_managers()\n        for j, figman in enumerate(fig_managers):\n            if len(fig_managers) == 1 and len(code_pieces) == 1:\n                img = ImageFile(output_base, output_dir)\n            elif len(code_pieces) == 1:\n                img = ImageFile(\"%s_%02d\" % (output_base, j), output_dir)\n            else:\n                img = ImageFile(\"%s_%02d_%02d\" % (output_base, i, j),\n                                output_dir)\n            images.append(img)\n            for format, dpi in formats:\n                try:\n                    figman.canvas.figure.tight_layout()\n                    figman.canvas.figure.savefig(img.filename(format),\n                                                 dpi=dpi,\n                                                 bbox_inches='tight')\n                except Exception as err:\n                    raise PlotError(traceback.format_exc())\n                img.formats.append(format)\n\n        results.append((code_piece, images))\n\n    if not context or config.plot_apply_rcparams:\n        clear_state(config.plot_rcparams, close=not context)\n\n    return results\n\n\ndef run(arguments, content, options, state_machine, state, lineno):\n    # The user may provide a filename *or* Python code content, but not both\n    if arguments and content:\n        raise RuntimeError(\"plot:: directive can't have both args and content\")\n\n    document = state_machine.document\n    config = document.settings.env.config\n    nofigs = 'nofigs' in options\n\n    options.setdefault('include-source', config.plot_include_source)\n    keep_context = 'context' in options\n    context_opt = None if not keep_context else options['context']\n\n    rst_file = document.attributes['source']\n    rst_dir = os.path.dirname(rst_file)\n\n    if len(arguments):\n        if not config.plot_basedir:\n            source_file_name = os.path.join(setup.app.builder.srcdir,\n                                            directives.uri(arguments[0]))\n        else:\n            source_file_name = os.path.join(setup.confdir, config.plot_basedir,\n                                            directives.uri(arguments[0]))\n\n        # If there is content, it will be passed as a caption.\n        caption = '\\n'.join(content)\n\n        # If the optional function name is provided, use it\n        if len(arguments) == 2:\n            function_name = arguments[1]\n        else:\n            function_name = None\n\n        with io.open(source_file_name, 'r', encoding='utf-8') as fd:\n            code = fd.read()\n        output_base = os.path.basename(source_file_name)\n    else:\n        source_file_name = rst_file\n        code = textwrap.dedent(\"\\n\".join(map(str, content)))\n        counter = document.attributes.get('_plot_counter', 0) + 1\n        document.attributes['_plot_counter'] = counter\n        base, ext = os.path.splitext(os.path.basename(source_file_name))\n        output_base = '%s-%d.py' % (base, counter)\n        function_name = None\n        caption = ''\n\n    base, source_ext = os.path.splitext(output_base)\n    if source_ext in ('.py', '.rst', '.txt'):\n        output_base = base\n    else:\n        source_ext = ''\n\n    # ensure that LaTeX includegraphics doesn't choke in foo.bar.pdf filenames\n    output_base = output_base.replace('.', '-')\n\n    # is it in doctest format?\n    is_doctest = contains_doctest(code)\n    if 'format' in options:\n        if options['format'] == 'python':\n            is_doctest = False\n        else:\n            is_doctest = True\n\n    # determine output directory name fragment\n    source_rel_name = relpath(source_file_name, setup.confdir)\n    source_rel_dir = os.path.dirname(source_rel_name)\n    while source_rel_dir.startswith(os.path.sep):\n        source_rel_dir = source_rel_dir[1:]\n\n    # build_dir: where to place output files (temporarily)\n    build_dir = os.path.join(os.path.dirname(setup.app.doctreedir),\n                             'plot_directive',\n                             source_rel_dir)\n    # get rid of .. in paths, also changes pathsep\n    # see note in Python docs for warning about symbolic links on Windows.\n    # need to compare source and dest paths at end\n    build_dir = os.path.normpath(build_dir)\n\n    if not os.path.exists(build_dir):\n        os.makedirs(build_dir)\n\n    # output_dir: final location in the builder's directory\n    dest_dir = os.path.abspath(os.path.join(setup.app.builder.outdir,\n                                            source_rel_dir))\n    if not os.path.exists(dest_dir):\n        os.makedirs(dest_dir) # no problem here for me, but just use built-ins\n\n    # how to link to files from the RST file\n    dest_dir_link = os.path.join(relpath(setup.confdir, rst_dir),\n                                 source_rel_dir).replace(os.path.sep, '/')\n    try:\n        build_dir_link = relpath(build_dir, rst_dir).replace(os.path.sep, '/')\n    except ValueError:\n        # on Windows, relpath raises ValueError when path and start are on\n        # different mounts/drives\n        build_dir_link = build_dir\n    source_link = dest_dir_link + '/' + output_base + source_ext\n\n    # make figures\n    try:\n        results = render_figures(code,\n                                 source_file_name,\n                                 build_dir,\n                                 output_base,\n                                 keep_context,\n                                 function_name,\n                                 config,\n                                 context_reset=context_opt == 'reset',\n                                 close_figs=context_opt == 'close-figs')\n        errors = []\n    except PlotError as err:\n        reporter = state.memo.reporter\n        sm = reporter.system_message(\n            2, \"Exception occurred in plotting %s\\n from %s:\\n%s\" % (output_base,\n                                                source_file_name, err),\n            line=lineno)\n        results = [(code, [])]\n        errors = [sm]\n\n    # Properly indent the caption\n    caption = '\\n'.join('      ' + line.strip()\n                        for line in caption.split('\\n'))\n\n    # generate output restructuredtext\n    total_lines = []\n    for j, (code_piece, images) in enumerate(results):\n        if options['include-source']:\n            if is_doctest:\n                lines = ['']\n                lines += [row.rstrip() for row in code_piece.split('\\n')]\n            else:\n                lines = ['.. code-block:: python', '']\n                lines += ['    %s' % row.rstrip()\n                          for row in code_piece.split('\\n')]\n            source_code = \"\\n\".join(lines)\n        else:\n            source_code = \"\"\n\n        if nofigs:\n            images = []\n\n        opts = [':%s: %s' % (key, val) for key, val in six.iteritems(options)\n                if key in ('alt', 'height', 'width', 'scale', 'align', 'class')]\n\n        only_html = \".. only:: html\"\n        only_latex = \".. only:: latex\"\n        only_texinfo = \".. only:: texinfo\"\n\n        # Not-None src_link signals the need for a source link in the generated\n        # html\n        if j == 0 and config.plot_html_show_source_link:\n            src_link = source_link\n        else:\n            src_link = None\n\n        result = format_template(\n            config.plot_template or TEMPLATE,\n            dest_dir=dest_dir_link,\n            build_dir=build_dir_link,\n            source_link=src_link,\n            multi_image=len(images) > 1,\n            only_html=only_html,\n            only_latex=only_latex,\n            only_texinfo=only_texinfo,\n            options=opts,\n            images=images,\n            source_code=source_code,\n            html_show_formats=config.plot_html_show_formats and not nofigs,\n            caption=caption)\n\n        total_lines.extend(result.split(\"\\n\"))\n        total_lines.extend(\"\\n\")\n\n    if total_lines:\n        state_machine.insert_input(total_lines, source=source_file_name)\n\n    # copy image files to builder's output directory, if necessary\n    if not os.path.exists(dest_dir):\n        cbook.mkdirs(dest_dir)\n\n    for code_piece, images in results:\n        for img in images:\n            for fn in img.filenames():\n                destimg = os.path.join(dest_dir, os.path.basename(fn))\n                if fn != destimg:\n                    shutil.copyfile(fn, destimg)\n\n    # copy script (if necessary)\n    target_name = os.path.join(dest_dir, output_base + source_ext)\n    with io.open(target_name, 'w', encoding=\"utf-8\") as f:\n        if source_file_name == rst_file:\n            code_escaped = unescape_doctest(code)\n        else:\n            code_escaped = code\n        f.write(code_escaped)\n\n    return errors\n"
  },
  {
    "path": "setup.py",
    "content": "import os\nfrom setuptools import setup\n\ninstall_requires = ['matplotlib', 'numpy', 'pandas']\n\ntry:\n    with open('README.rst') as readme:\n        long_description = readme.read()\nexcept IOError:\n    long_description = 'See https://pypi.python.org/pypi/calmap'\n\n# This is quite the hack, but we don't want to import our package from here\n# since that's recipe for disaster (it might have some uninstalled\n# dependencies, or we might import another already installed version).\ndistmeta = {}\nfor line in open(os.path.join('calmap', '__init__.py')):\n    try:\n        field, value = (x.strip() for x in line.split('='))\n    except ValueError:\n        continue\n    if field == '__version_info__':\n        value = value.strip('[]()')\n        value = '.'.join(x.strip(' \\'\"') for x in value.split(','))\n    else:\n        value = value.strip('\\'\"')\n    distmeta[field] = value\n\nsetup(\n    name='calmap',\n    version=distmeta['__version_info__'],\n    description='Calendar heatmaps from Pandas time series data',\n    long_description=long_description,\n    author=distmeta['__author__'],\n    author_email=distmeta['__contact__'],\n    url=distmeta['__homepage__'],\n    license='MIT License',\n    platforms=['any'],\n    packages=['calmap'],\n    install_requires=install_requires,\n    classifiers=[\n        'Development Status :: 3 - Alpha',\n        'Intended Audience :: Developers',\n        'Intended Audience :: Science/Research',\n        'Operating System :: OS Independent',\n        'Programming Language :: Python',\n        'Programming Language :: Python :: 2',\n        'Programming Language :: Python :: 2.7',\n        'Programming Language :: Python :: 3',\n        'Programming Language :: Python :: 3.4',\n        'Programming Language :: Python :: 3.5',\n        'Topic :: Scientific/Engineering']\n)\n"
  },
  {
    "path": "tests/conftest.py",
    "content": "import matplotlib\n\nmatplotlib.use('agg')\n"
  },
  {
    "path": "tests/requirements.txt",
    "content": "pytest==2.8.5\npytest-mpl==0.3\n"
  },
  {
    "path": "tests/test_calmap.py",
    "content": "\"\"\"\nTests for calmap.\n\"\"\"\n\n\nfrom __future__ import unicode_literals\n\nimport numpy as np; np.random.seed(sum(map(ord, 'calmap')))\nimport pandas as pd\nimport pytest\n\nimport calmap\n\n\n@pytest.fixture\ndef events():\n    \"\"\"\n    We create 500 events as random float values assigned to random days over a\n    700-day period.\n    \"\"\"\n    all_days = pd.date_range('1/15/2014', periods=700, freq='D')\n    days = np.random.choice(all_days, 500)\n    return pd.Series(np.random.randn(len(days)), index=days)\n\n\n@pytest.mark.mpl_image_compare(tolerance=20)\ndef test_yearplot(events):\n    \"\"\"\n    By default, `yearplot` plots the first year and sums the values per day.\n    \"\"\"\n    ax = calmap.yearplot(events)\n    return ax.figure\n\n\n@pytest.mark.mpl_image_compare(tolerance=20)\ndef test_yearplot_year(events):\n    \"\"\"\n    We can choose which year is plotted with the `year` keyword argment.\n    \"\"\"\n    ax = calmap.yearplot(events, year=2015)\n    return ax.figure\n\n\n@pytest.mark.mpl_image_compare(tolerance=20)\ndef test_yearplot_cmap_fillcolor_linewidth(events):\n    \"\"\"\n    The appearance can be changed by using another colormap. Here we also use\n    a darker fill color for days without data and remove the lines.\n    \"\"\"\n    ax = calmap.yearplot(events, cmap='YlGn', fillcolor='grey', linewidth=0)\n    return ax.figure\n\n\n@pytest.mark.mpl_image_compare(tolerance=20)\ndef test_yearplot_monthticks_daylabels_dayticks(events):\n    \"\"\"\n    We can ask to draw only every nth label, or explicitely supply the label\n    indices. The labels themselves can also be customized.\n    \"\"\"\n    ax = calmap.yearplot(events, monthticks=3, daylabels='MTWTFSS',\n                         dayticks=[0, 2, 4, 6])\n    return ax.figure\n\n\n@pytest.mark.mpl_image_compare(tolerance=50)\ndef test_calendarplot(events):\n    \"\"\"\n    With `calendarplot` we can plot several years in one figure.\n    \"\"\"\n    fig, axes = calmap.calendarplot(events)\n    return fig\n"
  }
]