proplot-dev / proplot

🎨 A succinct matplotlib wrapper for making beautiful, publication-quality graphics
https://proplot.readthedocs.io
MIT License
1.08k stars 100 forks source link

Hi-res plots can be quite slow #4

Closed aaronspring closed 5 years ago

aaronspring commented 5 years ago

I just learned about this nice wrapper, but for me it takes too long to plot large xr.dataarray's.

I make the call control3d.isel(time=1).plot() and then after one second this appears as should <matplotlib.collections.QuadMesh at 0x1c203e94a8> and then it takes around one minute for the plot to appear. It's a (time: 1, x: 256, y: 220) dataarray of 1.35MB.

When I use hydrogen inside the atom editor it works like a charm (fast).


aaron.spring@d147-139:~$ conda list
# packages in environment at /Users/aaron.spring/anaconda3:
#
# Name                    Version                   Build  Channel
_ipyw_jlab_nb_ext_conf    0.1.0                    py36_0
alabaster                 0.7.12                     py_0    conda-forge
altair                    2.3.0                 py36_1001    conda-forge
anaconda                  custom           py36ha4fed55_0
anaconda-client           1.7.1                      py_0    conda-forge
anaconda-navigator        1.9.6                    py36_0
anaconda-project          0.8.2                      py_1    conda-forge
appdirs                   1.4.3                     <pip>
appnope                   0.1.0                 py36_1000    conda-forge
appscript                 1.0.1            py36h470a237_0    conda-forge
asn1crypto                0.24.0                py36_1003    conda-forge
astroid                   2.1.0                 py36_1000    conda-forge
astropy                   3.1              py36h470a237_0    conda-forge
atomicwrites              1.2.1                      py_0    conda-forge
attrs                     18.2.0                     py_0    conda-forge
autopep8                  1.4.1                      py_0    conda-forge
babel                     2.6.0                      py_1    conda-forge
backcall                  0.1.0                      py_0    conda-forge
backports                 1.0                        py_2    conda-forge
backports.shutil_get_terminal_size 1.0.0                      py_3    conda-forge
beautifulsoup4            4.6.3                 py36_1000    conda-forge
bitarray                  0.8.3            py36h470a237_0    conda-forge
bkcharts                  0.2                      py36_0    conda-forge
black                     18.9b0                    <pip>
blas                      1.0                         mkl
blaze                     0.11.3                   py36_0    conda-forge
bleach                    3.0.1                      py_0    conda-forge
blinker                   1.4                        py_1    conda-forge
blosc                     1.14.4               hfc679d8_0    conda-forge
bokeh                     1.0.2                 py36_1000    conda-forge
boost-cpp                 1.67.0               h3a22d5f_0    conda-forge
boto                      2.49.0                   py36_0
boto3                     1.9.20                     py_0    conda-forge
botocore                  1.12.20                    py_0    conda-forge
bottleneck                1.2.1            py36h7eb728f_1    conda-forge
branca                    0.3.0                      py_0    conda-forge
bz2file                   0.98                       py_0    conda-forge
bzip2                     1.0.6                         1    conda-forge
ca-certificates           2018.11.29           ha4d7672_0    conda-forge
cairo                     1.14.12              he6fea26_5    conda-forge
cartopy                   0.17.0           py36h81b52dc_0    conda-forge
cdo                       1.9.5                h249571a_5    conda-forge
certifi                   2018.11.29            py36_1000    conda-forge
cffi                      1.11.5           py36h5e8e0c9_1    conda-forge
cftime                    1.0.3.4          py36h7eb728f_0    conda-forge
chardet                   3.0.4                 py36_1003    conda-forge
cite2c                    0.2.1                     <pip>
clangdev                  6.0.1                 default_1    conda-forge
click                     7.0                        py_0    conda-forge
click-plugins             1.0.4                      py_0    conda-forge
cligj                     0.5.0                      py_0    conda-forge
cloudpickle               0.6.0                      py_0    conda-forge
clyent                    1.2.2                      py_1    conda-forge
cmocean                   1.2                        py_0    conda-forge
colorama                  0.3.9                      py_1    conda-forge
conda                     4.5.12                py36_1000    conda-forge
conda-build               3.17.5                   py36_0    conda-forge
conda-env                 2.6.0                         1    conda-forge
conda-verify              3.1.1                 py36_1000    conda-forge
contextlib2               0.5.5                      py_2    conda-forge
cryptography              2.2.1            py36hdffb7b8_1    conda-forge
cryptography-vectors      2.4.2                   py_1000    conda-forge
curl                      7.61.1               h74213dd_2    conda-forge
cycler                    0.10.0                    <pip>
cycler                    0.10.0                     py_1    conda-forge
cython                    0.29.2           py36hfc679d8_0    conda-forge
cytoolz                   0.9.0.1          py36h470a237_1    conda-forge
dask                      1.0.0                      py_0    conda-forge
dask-core                 1.0.0                      py_0    conda-forge
datashape                 0.5.4                    py36_0    conda-forge
dbus                      1.13.0               h3a4f0e9_0    conda-forge
decorator                 4.3.0                      py_0    conda-forge
descartes                 1.1.0                      py_2    conda-forge
distributed               1.25.1                py36_1000    conda-forge
docutils                  0.14                  py36_1001    conda-forge
eccodes                   2.9.2                hc15e6af_1    conda-forge
entrypoints               0.2.3                 py36_1002    conda-forge
eofs                      1.3.0                      py_1    conda-forge
esmf                      7.1.0r               h35eb876_3    conda-forge
esmpy                     7.1.0r                   py36_1    conda-forge
et_xmlfile                1.0.1                 py36_1000    conda-forge
expat                     2.2.5                hfc679d8_2    conda-forge
fastcache                 1.0.2            py36h470a237_1    conda-forge
fftw                      3.3.8                h470a237_1    conda-forge
filelock                  3.0.9                      py_0    conda-forge
fiona                     1.7.13           py36hb00a9d7_4    conda-forge
flake8                    3.5.0                 py36_1000    conda-forge
flask                     1.0.2                      py_2    conda-forge
flask-cors                3.0.6                      py_0    conda-forge
folium                    0.6.0                      py_0    conda-forge
fontconfig                2.13.1               hce039c3_0    conda-forge
freetype                  2.9.1                h6debe1e_4    conda-forge
freexl                    1.0.5                h470a237_2    conda-forge
future                    0.17.0                py36_1000    conda-forge
gdal                      2.2.4           py36hb00a9d7_10    conda-forge
gensim                    3.4.0            py36h1de35cc_0
geographiclib             1.49                       py_0    conda-forge
geopandas                 0.4.0                      py_1    conda-forge
geopy                     1.17.0                     py_0    conda-forge
geos                      3.6.2                hfc679d8_3    conda-forge
geotiff                   1.4.2                h700e5ad_4    conda-forge
get_terminal_size         1.0.0                h7520d66_0
gettext                   0.19.8.1             h1f1d5ed_1    conda-forge
gevent                    1.3.7            py36h470a237_0    conda-forge
giflib                    5.1.4                h470a237_1    conda-forge
gitdb2                    2.0.5                     <pip>
GitPython                 2.1.11                    <pip>
glib                      2.55.0               h464dc38_2    conda-forge
glob2                     0.6                        py_0    conda-forge
gmp                       6.1.2                hfc679d8_0    conda-forge
gmpy2                     2.0.8            py36hb705a9b_2    conda-forge
greenlet                  0.4.13                   py36_0    conda-forge
h5netcdf                  0.6.2                      py_0    conda-forge
h5py                      2.8.0            py36h097b052_4    conda-forge
hdf4                      4.2.13               h951d187_2    conda-forge
hdf5                      1.10.3               hc401514_2    conda-forge
heapdict                  1.0.0                 py36_1000    conda-forge
holoviews                 1.10.9                     py_0    pyviz
html5lib                  1.0.1                      py_0    conda-forge
hvplot                    0.2.1                      py_0    pyviz
icu                       58.2                 hfc679d8_0    conda-forge
idna                      2.8                   py36_1000    conda-forge
imageio                   2.3.0                      py_1    conda-forge
imagesize                 1.1.0                      py_0    conda-forge
intel-openmp              2019.0                      118
ipykernel                 5.1.0           py36h24bf2e0_1001    conda-forge
ipyleaflet                0.8.1                    py36_0    conda-forge
ipython                   7.2.0           py36h24bf2e0_1000    conda-forge
ipython_genutils          0.2.0                      py_1    conda-forge
ipywidgets                7.4.2                      py_0    conda-forge
isort                     4.3.4                 py36_1000    conda-forge
itsdangerous              0.24                       py_2    conda-forge
jasper                    1.900.1              hff1ad4c_5    conda-forge
jbig                      2.1               h470a237_1001    conda-forge
jdcal                     1.4                        py_1    conda-forge
jedi                      0.13.2                py36_1000    conda-forge
jinja2                    2.10                       py_1    conda-forge
jmespath                  0.9.3                      py_1    conda-forge
jpeg                      9c                   h470a237_1    conda-forge
json-c                    0.12.1               h470a237_1    conda-forge
jsonschema                3.0.0a3               py36_1000    conda-forge
jupyter                   1.0.0                      py_1    conda-forge
jupyter-kernel-gateway    2.1.0                     <pip>
jupyter_client            5.2.3                      py_1    conda-forge
jupyter_console           6.0.0                      py_0    conda-forge
jupyter_contrib_core      0.3.3                      py_2    conda-forge
jupyter_contrib_nbextensions 0.5.0                 py36_1000    conda-forge
jupyter_core              4.4.0                      py_0    conda-forge
jupyter_highlight_selected_word 0.2.0                 py36_1000    conda-forge
jupyter_latex_envs        1.4.4                 py36_1000    conda-forge
jupyter_nbextensions_configurator 0.4.0                 py36_1000    conda-forge
jupyterlab                0.34.12               py36_1000    conda-forge
jupyterlab-github         0.6.1                     <pip>
jupyterlab_launcher       0.13.1                     py_2    conda-forge
jupyterlab_server         0.2.0                      py_0    conda-forge
jupyterthemes             0.19.6                    <pip>
kealib                    1.4.10               hb88cf67_0    conda-forge
keyring                   17.0.0                py36_1000    conda-forge
kiwisolver                1.0.1                     <pip>
kiwisolver                1.0.1            py36h2d50403_2    conda-forge
krb5                      1.16.1               hbb41f41_0    conda-forge
lazy-object-proxy         1.3.1            py36h470a237_0    conda-forge
lesscpy                   0.13.0                    <pip>
libaec                    1.0.2                hfc679d8_1    conda-forge
libarchive                3.3.3                h823be47_0    conda-forge
libcurl                   7.61.1               hbdb9355_2    conda-forge
libcxx                    6.0.1                         0    conda-forge
libcxxabi                 4.0.1                hebd6815_0
libdap4                   3.19.1               h18059cb_1    conda-forge
libedit                   3.1.20170329         haf1bffa_1    conda-forge
libffi                    3.2.1                hfc679d8_5    conda-forge
libgdal                   2.2.4               hd83b57f_10    conda-forge
libgfortran               3.0.1                h93005f0_2
libiconv                  1.15                 h470a237_3    conda-forge
libkml                    1.3.0                hccc92b1_8    conda-forge
liblief                   0.9.0                h2a1bed3_0
libnetcdf                 4.6.1               h350cafa_11    conda-forge
libopenblas               0.3.3                hdc02c5d_3
libpng                    1.6.35               ha92aebf_2    conda-forge
libpq                     10.5                 hf16a0db_0    conda-forge
libsodium                 1.0.16               h470a237_1    conda-forge
libspatialindex           1.8.5                hfc679d8_3    conda-forge
libspatialite             4.3.0a              h3b29d86_23    conda-forge
libssh2                   1.8.0                h5b517e9_2    conda-forge
libtiff                   4.0.9                he6b73bb_2    conda-forge
libxml2                   2.9.8                h422b904_5    conda-forge
libxslt                   1.1.32               h88dbc4e_2    conda-forge
llvm-meta                 6.0.1                         0    conda-forge
llvmdev                   6.0.1                h2d50403_2    conda-forge
llvmlite                  0.26.0          py36h3fea490_1000    conda-forge
locket                    0.2.0                      py_2    conda-forge
lxml                      4.2.5            py36hc9114bc_0    conda-forge
lzo                       2.10                          0    conda-forge
markupsafe                1.1.0            py36h470a237_0    conda-forge
matplotlib                3.0.0                     <pip>
matplotlib                3.0.2                    py36_1    conda-forge
matplotlib-base           3.0.2            py36hb2d221d_1    conda-forge
mccabe                    0.6.1                      py_1    conda-forge
mistune                   0.8.4            py36h470a237_0    conda-forge
mkl                       2018.0.3                      1
mkl-service               1.1.2            py36h6b9c3cc_5
mkl_fft                   1.0.10                   py36_0    conda-forge
mkl_random                1.0.2                    py36_0    conda-forge
more-itertools            4.3.0                 py36_1000    conda-forge
mpc                       1.1.0                hb705a9b_6    conda-forge
mpfr                      4.0.1                h16a7912_0    conda-forge
mpi                       1.0                       mpich    conda-forge
mpich                     3.2.1                h26a2512_7    conda-forge
mpmath                    1.0.0                      py_1    conda-forge
msgpack-python            0.6.0            py36h2d50403_0    conda-forge
multipledispatch          0.6.0                      py_0    conda-forge
munch                     2.3.2                      py_0    conda-forge
navigator-updater         0.2.1                    py36_0
nbconvert                 5.3.1                      py_1    conda-forge
nbdime                    1.0.3                     <pip>
nbformat                  4.4.0                      py_1    conda-forge
ncurses                   6.1                  hfc679d8_1    conda-forge
netcdf-fortran            4.4.4               h71ea97b_10    conda-forge
netcdf4                   1.4.2            py36hac939d9_0    conda-forge
networkx                  2.2                        py_1    conda-forge
nltk                      3.2.5                      py_0    conda-forge
nodejs                    10.8.0               hfc679d8_1    conda-forge
nose                      1.3.7                 py36_1002    conda-forge
notebook                  5.7.4                 py36_1000    conda-forge
notebook                  5.6.0                     <pip>
numba                     0.41.0           py36hf8a1672_0    conda-forge
numexpr                   2.6.8            py36hf8a1672_0    conda-forge
numpy                     1.15.4           py36h6a91979_0
numpy-base                1.15.4           py36h8a80b8c_0
numpydoc                  0.8.0                      py_1    conda-forge
oauthlib                  2.1.0                      py_0    conda-forge
odo                       0.5.1                      py_1    conda-forge
olefile                   0.46                       py_0    conda-forge
openblas                  0.2.20                        8    conda-forge
openjpeg                  2.3.0                h316dc23_3    conda-forge
openpyxl                  2.5.8                      py_0    conda-forge
openssl                   1.0.2p            h1de35cc_1002    conda-forge
osmnx                     0.8.2                      py_0    conda-forge
ossuuid                   1.6.2                hfc679d8_0    conda-forge
owslib                    0.17.0                     py_0    conda-forge
packaging                 18.0                       py_0    conda-forge
pandas                    0.23.4           py36hf8a1672_0    conda-forge
pandas-datareader         0.7.0                     <pip>
pandoc                    2.3.1                         0    conda-forge
pandocfilters             1.4.2                      py_1    conda-forge
param                     1.8.1                      py_0    pyviz
parso                     0.3.1                      py_0    conda-forge
partd                     0.3.8                      py_1    conda-forge
path.py                   11.0.1                     py_0    conda-forge
pathlib2                  2.3.3                 py36_1000    conda-forge
patsy                     0.5.0                      py_1    conda-forge
pcre                      8.41                 hfc679d8_3    conda-forge
pep8                      1.7.1                      py_0    conda-forge
pexpect                   4.6.0                 py36_1000    conda-forge
pickleshare               0.7.5                 py36_1000    conda-forge
pillow                    5.3.0            py36hc736899_0    conda-forge
pip                       18.1                      <pip>
pip                       18.1                  py36_1000    conda-forge
pixman                    0.34.0               h470a237_3    conda-forge
pkginfo                   1.4.2                      py_1    conda-forge
pluggy                    0.7.1                      py_0    conda-forge
ply                       3.11                       py_1    conda-forge
PMMPIESM                  0.1                       <pip>
poppler                   0.67.0               h4d7e492_3    conda-forge
poppler-data              0.4.9                         0    conda-forge
postgresql                10.5                 ha408888_0    conda-forge
proj4                     4.9.3                h470a237_8    conda-forge
prometheus-client         0.3.1                     <pip>
prometheus_client         0.4.1                      py_0    conda-forge
prompt_toolkit            2.0.5                      py_0    conda-forge
proplot                   1.0                       <pip>
psutil                    5.4.8            py36h470a237_0    conda-forge
psycopg2                  2.7.6.1          py36hdffb7b8_0    conda-forge
ptyprocess                0.6.0                 py36_1000    conda-forge
py                        1.6.0                      py_0    conda-forge
py-lief                   0.9.0            py36hd4eaf27_0
pycodestyle               2.4.0                      py_1    conda-forge
pycosat                   0.6.3            py36h470a237_1    conda-forge
pycparser                 2.19                       py_0    conda-forge
pycrypto                  2.6.1            py36h470a237_2    conda-forge
pycurl                    7.43.0.2         py36hdbc3d79_0
pydocstyle                3.0.0                     <pip>
pyepsg                    0.3.2                      py_1    conda-forge
pyfinance                 1.1.1                     <pip>
pyflakes                  1.6.0                      py_1    conda-forge
pygments                  2.2.0                      py_1    conda-forge
pyjwt                     1.6.4                      py_0    conda-forge
pykdtree                  1.3.1            py36h7eb728f_2    conda-forge
pylint                    2.2.2                 py36_1000    conda-forge
pyodbc                    4.0.25           py36hfc679d8_0    conda-forge
pyopenssl                 18.0.0                py36_1000    conda-forge
pyparsing                 2.3.0                     <pip>
pyparsing                 2.2.2                      py_0    conda-forge
pyproj                    1.9.5.1          py36h508ed2a_6    conda-forge
pyqt                      5.6.0            py36h8210e8a_8    conda-forge
pyrsistent                0.14.8           py36h470a237_0    conda-forge
pysal                     1.14.4.post2          py36_1001    conda-forge
pyshp                     1.2.12                     py_0    conda-forge
pysocks                   1.6.8                 py36_1002    conda-forge
pytables                  3.4.4            py36h55d7349_3    conda-forge
pytest                    4.0.2                 py36_1000    conda-forge
pytest-arraydiff          0.2                        py_0    conda-forge
pytest-astropy            0.4.0                      py_0    conda-forge
pytest-doctestplus        0.1.3                      py_0    conda-forge
pytest-openfiles          0.3.0                      py_0    conda-forge
pytest-remotedata         0.3.0                      py_0    conda-forge
python                    3.6.6                h5001a0f_0    conda-forge
python-cdo                1.4.0                      py_1    conda-forge
python-crfsuite           0.9.6            py36h2d50403_0    conda-forge
python-dateutil           2.7.5                     <pip>
python-dateutil           2.7.3                      py_0    conda-forge
python-jsonrpc-server     0.0.2                     <pip>
python-language-server    0.21.2                    <pip>
python-libarchive-c       2.8                   py36_1004    conda-forge
python.app                1.2             py36h470a237_200    conda-forge
pytz                      2018.7                    <pip>
pytz                      2018.5                     py_0    conda-forge
pyviz_comms               0.6.0                      py_0    pyviz
pywavelets                1.0.1            py36h7eb728f_0    conda-forge
pyyaml                    3.13             py36h470a237_1    conda-forge
pyzmq                     17.1.2           py36hae99301_1    conda-forge
pyzmq                     17.1.2                    <pip>
qt                        5.6.2                hd4c90f3_9    conda-forge
qtawesome                 0.5.1              pyh8a2030e_1    conda-forge
qtconsole                 4.4.3                      py_0    conda-forge
qtpy                      1.5.1              pyh8a2030e_0    conda-forge
rauth                     0.7.3                     <pip>
readline                  7.0                  haf1bffa_1    conda-forge
requests                  2.21.0                py36_1000    conda-forge
requests                  2.19.1                    <pip>
requests-oauthlib         1.0.0                      py_1    conda-forge
rope                      0.10.7                     py_1    conda-forge
rtree                     0.8.3                 py36_1000    conda-forge
ruamel_yaml               0.15.71          py36h470a237_0    conda-forge
s3transfer                0.1.13                py36_1001    conda-forge
scikit-image              0.14.1           py36hfc679d8_1    conda-forge
scikit-learn              0.20.1           py36h4f467ca_0
scipy                     1.1.0            py36h28f7352_1
seaborn                   0.9.0                     <pip>
seaborn                   0.9.0                      py_0    conda-forge
send2trash                1.5.0                      py_0    conda-forge
setuptools                40.6.3                   py36_0    conda-forge
shapely                   1.6.4            py36h164cb2d_1    conda-forge
simplegeneric             0.8.1                      py_1    conda-forge
singledispatch            3.4.0.3               py36_1000    conda-forge
sip                       4.18.1           py36hfc679d8_0    conda-forge
six                       1.12.0                py36_1000    conda-forge
smart_open                1.7.1                      py_0    conda-forge
smmap2                    2.0.5                     <pip>
snakeviz                  1.0.0                     <pip>
snowballstemmer           1.2.1                      py_1    conda-forge
sortedcollections         1.0.1                      py_1    conda-forge
sortedcontainers          2.0.5                      py_0    conda-forge
sphinx                    1.8.2                 py36_1000    conda-forge
sphinxcontrib             1.0                      py36_1
sphinxcontrib-websupport  1.1.0                      py_1    conda-forge
spyder                    3.3.2                 py36_1001    conda-forge
spyder-kernels            0.2.6                      py_1    conda-forge
sqlalchemy                1.2.15           py36h470a237_0    conda-forge
sqlite                    3.26.0               hb1c47c0_0    conda-forge
statsmodels               0.9.0            py36h7eb728f_0    conda-forge
sympy                     1.3                   py36_1000    conda-forge
tblib                     1.3.2                      py_1    conda-forge
terminado                 0.8.1                 py36_1001    conda-forge
testpath                  0.4.2                 py36_1000    conda-forge
tk                        8.6.8                ha92aebf_0    conda-forge
toml                      0.10.0                    <pip>
toolz                     0.9.0                      py_1    conda-forge
tornado                   5.1.1            py36h470a237_0    conda-forge
tqdm                      4.26.0                     py_0    conda-forge
traitlets                 4.3.2                 py36_1000    conda-forge
traittypes                0.2.1                      py_1    conda-forge
twython                   3.7.0                      py_0    conda-forge
typed-ast                 1.1.1            py36h470a237_0    conda-forge
typing                    3.6.4                    py36_0    conda-forge
udunits2                  2.2.27.6             h3a4f0e9_1    conda-forge
unicodecsv                0.14.1                     py_1    conda-forge
unixodbc                  2.3.7                h09ba92c_0    conda-forge
urllib3                   1.23                  py36_1001    conda-forge
vincent                   0.4.4                      py_1    conda-forge
wcwidth                   0.1.7                      py_1    conda-forge
webencodings              0.5.1                      py_1    conda-forge
werkzeug                  0.14.1                     py_0    conda-forge
wheel                     0.32.3                   py36_0    conda-forge
widgetsnbextension        3.4.2                 py36_1000    conda-forge
wrapt                     1.10.11          py36h470a237_1    conda-forge
xarray                    0.11.2                py36_1000    conda-forge
xerces-c                  3.2.0                h5d6a6da_2    conda-forge
xesmf                     0.1.1                    py36_0    conda-forge
xlrd                      1.1.0                      py_2    conda-forge
xlsxwriter                1.1.1                      py_0    conda-forge
xlwings                   0.15.1                   py36_0    conda-forge
xlwt                      1.3.0                      py_1    conda-forge
xmltodict                 0.11.0                    <pip>
xz                        5.2.4                h470a237_1    conda-forge
yaml                      0.1.7                h470a237_1    conda-forge
yapf                      0.24.0                    <pip>
zeromq                    4.2.5                hfc679d8_5    conda-forge
zict                      0.1.3                      py_0    conda-forge
zlib                      1.2.11               h470a237_3    conda-forge
aaronspring commented 5 years ago

Without proplot this plots fast. Even when I use cartopy projections.

bradyrx commented 5 years ago

@aaronspring , the below runs in 364ms on my Jupyter notebook. This might be an atom issue or other issues in the demo notebook. I can look at it more closely tomorrow.

import proplot as plot
from climpred.loadutils import open_dataset
control3d = open_dataset('MPI-control-3D')['tos']
control3d.isel(time=1).plot()
aaronspring commented 5 years ago

Maybe some extension in jupyter lab I installed. Less than a second is totally fine. I will check this tomorrow.

aaronspring commented 5 years ago

I just checked with jupyter notebook. I also get the problem there.

aaronspring commented 5 years ago

aaron.spring@d147-139:~/Coding/climpred$ jupyter labextension list
JupyterLab v0.34.12
Known labextensions:
   app dir: /Users/aaron.spring/anaconda3/share/jupyter/lab
        @jupyterlab/celltags v0.1.4  enabled  OK
        @jupyterlab/git v0.2.2  enabled  OK
        @jupyterlab/github v0.9.0  enabled  OK
        @jupyterlab/latex v0.5.0  enabled  OK
        @jupyterlab/shortcutui v0.3.1  enabled  OK
        @jupyterlab/statusbar v0.4.3  enabled  OK
        @jupyterlab/toc v0.5.0  enabled  OK
        @ryantam626/jupyterlab_code_formatter v0.1.5  enabled  OK
        nbdime-jupyterlab v0.6.0  enabled   X

"nbdime-jupyterlab@0.6.0" is not compatible with the current JupyterLab
Conflicting Dependencies:
JupyterLab             Extension        Package
>=0.18.4 <0.19.0       >=0.19.1 <0.20.0 @jupyterlab/apputils
>=0.18.5 <0.19.0       >=0.19.1 <0.20.0 @jupyterlab/notebook
>=0.18.4 <0.19.0       >=0.19.1 <0.20.0 @jupyterlab/rendermime
bradyrx commented 5 years ago

This might be an issue to raise in climpred and close here. It seems like a problem with your workflow/environment and not proplot itself.

bradyrx commented 5 years ago

@lukelbd, actually, I'm with @aaronspring on this one. proplot is slowing down any sort of cartopy plotting to the point of being unusable. Without proplot cartopy plots in O(100ms); with it, it plots in O(1 minute). I tested this on my personal machine and Cheyenne.

Generate data:

import numpy as np
import xarray as xr
x = np.random.rand(180, 360)
lat = np.linspace(-89.5, 89.5, 180)
lon = np.linspace(-179.5, 179.5, 360)
data = xr.DataArray(x, dims=['lat', 'lon'], coords=[lat, lon])

Without proplot:

import matplotlib.pyplot as plt
import cartopy.crs as ccrs
f, ax = plt.subplots(figsize=(8,3),
                     subplot_kw=dict(projection=ccrs.PlateCarree()))
ax.pcolormesh(data.lon, data.lat, data, transform=ccrs.PlateCarree())
ax.coastlines()
# runtime: 271ms

With proplot:

import proplot as plot
f, ax = plot.subplots(proj='hammer')
ax.pcolormesh(data.lon, data.lat, data.transpose())
# runtime: 72s
lukelbd commented 5 years ago

Hmm, very weird. Thanks for the working example.

Was the plot produced by proplot way higher res? Because when I use the default (blurry; think it's called "GTK") matplotlib backend, both cells execute in milliseconds (matplotlib around 0.04s, proplot around 0.07s). But with the hi-res backend enabled by plot.nbsetup(), I get matplotlib at 40s, and proplot at 47s.

Could your rendering backend (the library used to turn matplotlib.figure.Figure objects into inline graphics) have changed between those two tests? Try the following three cells, both with and without the plot.nbsetup() command. You will have to restart your notebook session between tests.

import numpy as np
import xarray as xr
import proplot as plot
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
plot.nbsetup() # try commenting out this line
x = np.random.rand(180, 360)
lat = np.linspace(-89.5, 89.5, 180)
lon = np.linspace(-179.5, 179.5, 360)
data = xr.DataArray(x, dims=['lat', 'lon'], coords=[lat, lon])

Matplotlib test:

@plot.timer
def test1():
    f, ax = plt.subplots(figsize=(8,3),
                         subplot_kw=dict(projection=ccrs.PlateCarree()))
    ax.pcolormesh(data.lon, data.lat, data, transform=ccrs.PlateCarree())
    ax.coastlines()
    plt.show()
test1()

Proplot test:

@plot.timer
def test2():
    f, ax = plot.subplots(proj='platecarree')
    ax.pcolormesh(data.lon, data.lat, data.T)
    ax.format(coastline=True)
    plt.show()
test2()

plot.nbsetup() enables a hi-res default viewer, more suitable for my default "small" font sizes, axes sizes, etc. Generally I save figures as PDFs, so that when figures show up in print, they do not have to be scaled up or down -- font sizes around 8-12 are correct I think for journals. For presentations/posters/posting online, that's when I scale stuff up and down, because these are more loose formats anyway.

For this particular case, I recommend not using plot.nbsetup(), or preferably, when you have reasonably hi-res and not-particularly-noisy data, use contour or contourf instead of pcolor. The former takes way less file space/processing power, because with pcolor, you have to render tens to hundreds of thousands of little boxes, but with contour, you just have to render 10-20 lines.

Maybe my hypothesis is wrong though?


Sidenote: I realize now I should be more accommodating to different workflows. One thing on the post-Masters to-do list is allow users to change the defaults that I have currently set in rcmod.py. Maybe I'll let people have a ~/.proplotrc file that can be used to change the default "global" properties, analogous to ~/.matplotlibrc. And I can also make rcmod.py respect any settings found in ~/.matplotlibrc, instead of overriding everything like it currently does.

bradyrx commented 5 years ago

Was the plot produced by proplot way higher res? But with the hi-res backend enabled by plot.nbsetup(), I get matplotlib at 40s, and proplot at 47s.

So this is after running plot.nbsetup(). I run this blindly at the start of every notebook, so maybe I should see what all it's doing. One thing I noticed is that my y-axis labels get cut off the notebook figures unless I run that setup command, so I always do it. I didn't think about it causing high-res matplotlib images.

Here's the results of my testing:

plot.nbsetup() ON plot.nbsetup() OFF
matplotlib pcolormesh 30.1s 0.2s
matplotlib contourf 6.3s 3.8s
proplot pcolormesh 35.2s 2.5s
proplot contourf 175s 60.7s

Okay, maybe not the most fair comparison with contourf. I realize now I fed in that np.random() which made contouring ridiculous, but I don't have time right now to re-run everything.

For this particular case, I recommend not using plot.nbsetup(), or preferably, when you have reasonably hi-res and not-particularly-noisy data, use contour or contourf instead of pcolor. The former takes way less file space/processing power, because with pcolor, you have to render tens to hundreds of thousands of little boxes, but with contour, you just have to render 10-20 lines.

I think the best deal for me is to avoid plot.nbsetup(). I work mainly with POP (irregular structured mesh) or MPAS (unstructured mesh) so contour/contourf do not work unless I remap to a standard grid. Maybe you have a workaround for this, but if you feed contourf a grid with the pole centered on Greenland for instance, it plots all these weird streaks across it. So I tend to remap to 360x180 using CDO/NCO and plot the contour from there.


Sidenote: I realize now I should be more accommodating to different workflows. One thing on the post-Masters to-do list is allow users to change the defaults that I have currently set in rcmod.py. Maybe I'll let people have a ~/.proplotrc file that can be used to change the default "global" properties, analogous to ~/.matplotlibrc. And I can also make rcmod.py respect any settings found in ~/.matplotlibrc, instead of overriding everything like it currently does.

This sounds reasonable to me. It's probably best practice to have a global config that one can modify settings via .proplotrc which is favored. I like it. matplotlibrc > proplotrc > globalrc

lukelbd commented 5 years ago

Thanks a lot for the table. Those times are definitely not ideal... will do some more extensive testing to figure out where the bottleneck is when I have the chance. Don't know why my test resulted in such a smaller time difference.

lukelbd commented 5 years ago

Hey, are you guys still having this problem?

I tried both the examples in this thread:

import proplot as plot
from climpred.loadutils import open_dataset
control3d = open_dataset('MPI-control-3D')['tos']
control3d.isel(time=1).plot()

and

import numpy as np
import xarray as xr
import proplot as plot
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
plot.nbsetup() # try commenting out this line
x = np.random.rand(180, 360)
lat = np.linspace(-89.5, 89.5, 180)
lon = np.linspace(-179.5, 179.5, 360)
data = xr.DataArray(x, dims=['lat', 'lon'], coords=[lat, lon])

# Pyplot test
from proplot.utils import _timer
@_timer
def test1():
    f, ax = plt.subplots(figsize=(8,3),
                         subplot_kw=dict(projection=ccrs.PlateCarree()))
    ax.pcolormesh(data.lon, data.lat, data, transform=ccrs.PlateCarree())
    ax.coastlines()
    plt.show()
test1()

# Proplot test
@_timer
def test2():
    f, ax = plot.subplots(proj='pcarree', figsize=(8,3))
    ax.pcolormesh(data.lon, data.lat, data)
    ax.format(coast=True)
test2()

and there's basically no time difference. Was there another dataset you were testing? Maybe one of the changes I've made in the last month magically fixed it?

P.S. Note there are a few differences since this example was last posted: (1) the _timer decorator is now hidden, and you have to import it directly, (2) you no longer have to transpose your data -- the convention is now the same as with matplotlib, "y by x", and (3) the projection name is now "pcarree" instead of "platecarree" -- valid projection names are shown in this table and for the most part correspond to their PROJ.4 names. The documentation is much better now, with the "quick start" and "showcase" merged into one comprehensive tutorial. And it's more suitable for collaboration now if you guys have any of your own ideas/want to submit a PR.

lukelbd commented 5 years ago

Actually ProPlot is slower, but not unusably slower. I'm getting with or without proplot.nbsetup (the second example with random data): about ~0.3s for pyplot, and ~1s for proplot.

It's really strange why proplot takes >0.5s longer. After some profiling all of the slowdown seems to be from the proplot.Figure.draw command (usually takes around 0.8s), but none of the slowdown is from my custom functions like smart_tight_layout (about 0.008s) -- it is all from the call to the native matplotlib matplotlib.figure.Figure.draw command. It even happens when I disable all calls to format. Maybe it has something to do with inherent inefficiencies in using subclassed axes and figure objects.

I have a hunch for where the original problem might have come from. I may have had reso='hi' as the default for all geographic features before. Plotting high-resolution geographic features takes a lot longer... up to 6s on my machine. Maybe it's even worse on yours? The ax.coastline() command uses low-resolution by default.

lukelbd commented 5 years ago

Figured out where the ~1s time difference was coming from! After fixing the following two things, pyplot and proplot speeds are roughly identical (+/- a few hundredths of a second):

  1. By default, wrapper_cmap fixes white lines between contour edges and white lines between pcolor edges, as discussed here. But this adds a whole bunch of new lines to render, which slows things down. Now, you can use fix=False in your call to ax.pcolormesh or ax.contourf to disable this.
  2. Previously, I always used LinearSegmentedNorm for colormap plots ("normalizers" convert data values into coordinates in the range [0,1], which correspond to points along the colormap). LinearSegmentedNorm gives you "even" color gradations across arbitrarily-spaced monotonic levels -- for example, with levels=[0, 0.1, 9.9, 10], the color intensity change between 0 and 0.1 will be the same as between 0.1 and 9.9. This is useful when you want levels that span a broad range of magnitudes, but the algorithm is pretty slow.

    Now, if the levels were automatically selected by matplotlib or if the user input levels are linearly spaced, I don't use this normalizer.

Download the latest version to try it out. Note nbsetup makes no difference in these times -- now that I know this, nbsetup is called every time you import ProPlot. You can disable this with the new nbsetup setting in your .proplotrc file.

Let me know if you guys still have issues.

aaronspring commented 5 years ago

now proplot only makes it a little slower for xr.plot() and even faster for xr.plot(cartopy.projections). However, when I do plot.nbsetup(), I still get fast timings with %time but still it takes 2 extra seconds for the plot to appear on screen.

bradyrx commented 5 years ago

Thanks @lukelbd for all this work. Looking forward to being able to jump fully to proplot with these faster timings!