Skip to content

Commit

Permalink
Merge cf53558 into bbb7258
Browse files Browse the repository at this point in the history
  • Loading branch information
kdebrab committed Apr 23, 2018
2 parents bbb7258 + cf53558 commit 56f2e5d
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 8 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ before_install:
- chmod +x miniconda.sh
- "./miniconda.sh -b -p /home/travis/mc"
- export PATH=/home/travis/mc/bin:$PATH
- export MPLBACKEND='Agg'
install:
- conda update --yes conda
- conda config --add channels soft-matter
Expand Down
4 changes: 2 additions & 2 deletions opengrid/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from opengrid.__about__ import __version__
import opengrid.library.analysis as analysis
from opengrid.library import analysis, plotting
from opengrid.library.regression import MultiVarLinReg
import opengrid.datasets as datasets
from opengrid import datasets
from opengrid.library.plotting import plot_style
108 changes: 104 additions & 4 deletions opengrid/library/plotting.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,116 @@
import matplotlib.pyplot as plt
import os
import numpy as np
import pandas as pd
import matplotlib
import matplotlib.cm as cm
import matplotlib.pyplot as plt
from matplotlib.dates import date2num, num2date, HourLocator, DayLocator, AutoDateLocator, DateFormatter
from matplotlib.colors import LogNorm


def plot_style():
try:
# matplotlib inline, only when jupyter notebook
# try-except causes problems in Pycharm Console
if 'JPY_PARENT_PID' in os.environ:
get_ipython().run_line_magic('matplotlib', 'inline')
except NameError:
pass

matplotlib.style.use('seaborn-talk')
matplotlib.style.use('seaborn-whitegrid')
matplotlib.style.use('seaborn-deep')

plt.rcParams['figure.figsize'] = 16, 6
return plt


def carpet(timeseries, **kwargs):
"""
Draw a carpet plot of a pandas timeseries.
The carpet plot reads like a letter. Every day one line is added to the
bottom of the figure, minute for minute moving from left (morning) to right
(evening).
The color denotes the level of consumption and is scaled logarithmically.
If vmin and vmax are not provided as inputs, the minimum and maximum of the
colorbar represent the minimum and maximum of the (resampled) timeseries.
Parameters
----------
timeseries : pandas.Series
vmin, vmax : If not None, either or both of these values determine the range
of the z axis. If None, the range is given by the minimum and/or maximum
of the (resampled) timeseries.
zlabel, title : If not None, these determine the labels of z axis and/or
title. If None, the name of the timeseries is used if defined.
cmap : matplotlib.cm instance, default coolwarm
Examples
--------
>>> import numpy as np
>>> import pandas as pd
>>> from opengrid.library import plotting
>>> plt = plotting.plot_style()
>>> index = pd.date_range('2015-1-1','2015-12-31',freq='h')
>>> ser = pd.Series(np.random.normal(size=len(index)), index=index, name='abc')
>>> im = plotting.carpet(ser)
"""

# define optional input parameters
cmap = kwargs.pop('cmap', cm.coolwarm)
norm = kwargs.pop('norm', LogNorm())
interpolation = kwargs.pop('interpolation', 'nearest')
cblabel = kwargs.pop('zlabel', timeseries.name if timeseries.name else '')
title = kwargs.pop('title', 'carpet plot: ' + timeseries.name if timeseries.name else '')

# data preparation
if timeseries.dropna().empty:
print('skipped {} - no data'.format(title))
return
ts = timeseries.resample('15min').interpolate()
vmin = max(0.1, kwargs.pop('vmin', ts[ts > 0].min()))
vmax = max(vmin, kwargs.pop('vmax', ts.quantile(.999)))

# convert to dataframe with date as index and time as columns by
# first replacing the index by a MultiIndex
mpldatetimes = date2num(ts.index.to_pydatetime())
ts.index = pd.MultiIndex.from_arrays(
[np.floor(mpldatetimes), 2 + mpldatetimes % 1]) # '2 +': matplotlib bug workaround.
# and then unstacking the second index level to columns
df = ts.unstack()

# data plotting

fig, ax = plt.subplots()
# define the extent of the axes (remark the +- 0.5 for the y axis in order to obtain aligned date ticks)
extent = [df.columns[0], df.columns[-1], df.index[-1] + 0.5, df.index[0] - 0.5]
im = plt.imshow(df, vmin=vmin, vmax=vmax, extent=extent, cmap=cmap, aspect='auto', norm=norm,
interpolation=interpolation, **kwargs)

# figure formatting

# x axis
ax.xaxis_date()
ax.xaxis.set_major_locator(HourLocator(interval=2))
ax.xaxis.set_major_formatter(DateFormatter('%H:%M'))
ax.xaxis.grid(True)
plt.xlabel('UTC Time')

# y axis
ax.yaxis_date()
dmin, dmax = ax.yaxis.get_data_interval()
number_of_days = (num2date(dmax) - num2date(dmin)).days
# AutoDateLocator is not suited in case few data is available
if abs(number_of_days) <= 35:
ax.yaxis.set_major_locator(DayLocator())
else:
ax.yaxis.set_major_locator(AutoDateLocator())
ax.yaxis.set_major_formatter(DateFormatter("%a, %d %b %Y"))

# plot colorbar
cbticks = np.logspace(np.log10(vmin), np.log10(vmax), 11, endpoint=True)
cb = plt.colorbar(format='%.0f', ticks=cbticks)
cb.set_label(cblabel)

# plot title
plt.title(title)

return im
14 changes: 12 additions & 2 deletions opengrid/tests/test_plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,21 @@
import unittest


class AnalysisTest(unittest.TestCase):
def test_plotting(self):
class PlotStyleTest(unittest.TestCase):
def test_default(self):
from opengrid.library.plotting import plot_style
plt = plot_style()


class CarpetTest(unittest.TestCase):
def test_default(self):
import numpy as np
import pandas as pd
from opengrid.library import plotting
index = pd.date_range('2015-1-1', '2015-12-31', freq='h')
ser = pd.Series(np.random.normal(size=len(index)), index=index, name='abc')
plotting.carpet(ser)


if __name__ == '__main__':
unittest.main()

0 comments on commit 56f2e5d

Please sign in to comment.