Skip to content

Commit

Permalink
Merge pull request #110 from pastas/dev
Browse files Browse the repository at this point in the history
Release pastastore 1.4.0
  • Loading branch information
dbrakenhoff authored Mar 22, 2024
2 parents 60b6569 + e0b96a3 commit 5debef8
Show file tree
Hide file tree
Showing 12 changed files with 285 additions and 65 deletions.
11 changes: 6 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Setup Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: 3.9
cache: "pip"
Expand Down Expand Up @@ -54,20 +54,21 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11"]
python-version: ["3.9", "3.10", "3.11"]
pastas-version:
[
"git+https://github.com/pastas/[email protected]",
"git+https://github.com/pastas/[email protected]",
"git+https://github.com/pastas/[email protected]",
"git+https://github.com/pastas/[email protected]",
"git+https://github.com/pastas/pastas.git@dev",
]

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: "pip"
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/python-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: '3.x'

Expand Down
2 changes: 1 addition & 1 deletion pastastore/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# ruff: noqa: F401
from pastastore import connectors, util
from pastastore import connectors, styling, util
from pastastore.connectors import (
ArcticConnector,
ArcticDBConnector,
Expand Down
125 changes: 109 additions & 16 deletions pastastore/plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
ax = pstore.maps.oseries()
pstore.maps.add_background_map(ax) # for adding a background map
"""

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
Expand Down Expand Up @@ -49,6 +50,9 @@ def _timeseries(
split=False,
figsize=(10, 5),
progressbar=True,
show_legend=True,
labelfunc=None,
legend_kwargs=None,
**kwargs,
):
"""Internal method to plot time series from pastastore.
Expand All @@ -71,6 +75,13 @@ def _timeseries(
progressbar : bool, optional
show progressbar when loading time series from store,
by default True
show_legend : bool, optional
show legend, default is True.
labelfunc : callable, optional
function to create custom labels, function should take name of time series
as input
legend_kwargs : dict, optional
additional arguments to pass to legend
Returns
-------
Expand Down Expand Up @@ -109,16 +120,33 @@ def _timeseries(
iax = axes
else:
iax = ax
if labelfunc is not None:
n = labelfunc(n)
iax.plot(ts.index, ts.squeeze(), label=n, **kwargs)
if split:

if split and show_legend:
iax.legend(loc="best", fontsize="x-small")

if not split:
axes.legend(loc=(0, 1), frameon=False, ncol=7, fontsize="x-small")
if not split and show_legend:
if legend_kwargs is None:
legend_kwargs = {}
ncol = legend_kwargs.pop("ncol", 7)
fontsize = legend_kwargs.pop("fontsize", "x-small")
axes.legend(loc=(0, 1), frameon=False, ncol=ncol, fontsize=fontsize)

return axes

def oseries(self, names=None, ax=None, split=False, figsize=(10, 5), **kwargs):
def oseries(
self,
names=None,
ax=None,
split=False,
figsize=(10, 5),
show_legend=True,
labelfunc=None,
legend_kwargs=None,
**kwargs,
):
"""Plot oseries.
Parameters
Expand All @@ -134,6 +162,13 @@ def oseries(self, names=None, ax=None, split=False, figsize=(10, 5), **kwargs):
A maximum of 20 time series is supported when split=True.
figsize : tuple, optional
figure size, by default (10, 5)
show_legend : bool, optional
show legend, default is True.
labelfunc : callable, optional
function to create custom labels, function should take name of time series
as input
legend_kwargs : dict, optional
additional arguments to pass to legend
Returns
-------
Expand All @@ -146,6 +181,9 @@ def oseries(self, names=None, ax=None, split=False, figsize=(10, 5), **kwargs):
ax=ax,
split=split,
figsize=figsize,
show_legend=show_legend,
labelfunc=labelfunc,
legend_kwargs=legend_kwargs,
**kwargs,
)

Expand All @@ -156,6 +194,9 @@ def stresses(
ax=None,
split=False,
figsize=(10, 5),
show_legend=True,
labelfunc=None,
legend_kwargs=None,
**kwargs,
):
"""Plot stresses.
Expand All @@ -176,6 +217,13 @@ def stresses(
A maximum of 20 time series is supported when split=True.
figsize : tuple, optional
figure size, by default (10, 5)
show_legend : bool, optional
show legend, default is True.
labelfunc : callable, optional
function to create custom labels, function should take name of time series
as input
legend_kwargs : dict, optional
additional arguments to pass to legend
Returns
-------
Expand All @@ -196,6 +244,9 @@ def stresses(
ax=ax,
split=split,
figsize=figsize,
show_legend=show_legend,
labelfunc=labelfunc,
legend_kwargs=legend_kwargs,
**kwargs,
)

Expand Down Expand Up @@ -511,6 +562,22 @@ def cumulative_hist(

return ax

def compare_models(self, modelnames, ax=None, **kwargs):
models = self.pstore.get_models(modelnames)
names = []
onames = [iml.oseries.name for iml in models]
if len(np.unique(onames)) == 1:
for modelname in modelnames:
if onames[0] in modelname:
names.append(modelname.replace(onames[0], ""))
else:
names.append(modelname)
else:
names = modelnames
cm = ps.CompareModels(models, names=names)
cm.plot(**kwargs)
return cm


class Maps:
"""Map Class for PastaStore.
Expand Down Expand Up @@ -539,10 +606,12 @@ def stresses(
self,
names=None,
kind=None,
extent=None,
labels=True,
adjust=False,
figsize=(10, 8),
backgroundmap=False,
label_kwargs=None,
**kwargs,
):
"""Plot stresses locations on map.
Expand All @@ -554,6 +623,8 @@ def stresses(
kind: str, optional
if passed, only plot stresses of a specific kind, default is None
which plots all stresses.
extent : list of float, optional
plot only stresses within extent [xmin, xmax, ymin, ymax]
labels: bool, optional
label models, by default True
adjust: bool, optional
Expand All @@ -565,6 +636,8 @@ def stresses(
backgroundmap: bool, optional
if True, add background map (default CRS is EPSG:28992) with default tiles
by OpenStreetMap.Mapnik. Default option is False.
label_kwargs: dict, optional
dictionary with keyword arguments to pass to add_labels method
Returns
-------
Expand All @@ -575,10 +648,10 @@ def stresses(
--------
self.add_background_map
"""
if names is not None:
df = self.pstore.stresses.loc[names]
else:
df = self.pstore.stresses
names = self.pstore.conn._parse_names(names, "stresses")
if extent is not None:
names = self.pstore.within(extent, names=names, libname="stresses")
df = self.pstore.stresses.loc[names]

if kind is not None:
if isinstance(kind, str):
Expand All @@ -603,7 +676,9 @@ def stresses(
else:
ax = r
if labels:
self.add_labels(stresses, ax, adjust=adjust)
if label_kwargs is None:
label_kwargs = {}
self.add_labels(stresses, ax, adjust=adjust, **label_kwargs)

if backgroundmap:
self.add_background_map(ax)
Expand All @@ -613,10 +688,12 @@ def stresses(
def oseries(
self,
names=None,
extent=None,
labels=True,
adjust=False,
figsize=(10, 8),
backgroundmap=False,
label_kwargs=None,
**kwargs,
):
"""Plot oseries locations on map.
Expand All @@ -625,15 +702,20 @@ def oseries(
----------
names: list, optional
oseries names, by default None which plots all oseries locations
labels: bool, optional
label models, by default True
extent : list of float, optional
plot only oseries within extent [xmin, xmax, ymin, ymax]
labels: bool or str, optional
label models, by default True, if passed as "grouped", only the first
label for each x,y-location is shown.
adjust: bool, optional
automated smart label placement using adjustText, by default False
figsize: tuple, optional
figure size, by default(10, 8)
backgroundmap: bool, optional
if True, add background map (default CRS is EPSG:28992) with default tiles
by OpenStreetMap.Mapnik. Default option is False.
label_kwargs: dict, optional
dictionary with keyword arguments to pass to add_labels method
Returns
-------
Expand All @@ -646,6 +728,8 @@ def oseries(
"""

names = self.pstore.conn._parse_names(names, "oseries")
if extent is not None:
names = self.pstore.within(extent, names=names)
oseries = self.pstore.oseries.loc[names]
mask0 = (oseries["x"] != 0.0) | (oseries["y"] != 0.0)
r = self._plotmap_dataframe(oseries.loc[mask0], figsize=figsize, **kwargs)
Expand All @@ -654,7 +738,12 @@ def oseries(
else:
ax = r
if labels:
self.add_labels(oseries, ax, adjust=adjust)
if label_kwargs is None:
label_kwargs = {}
if labels == "grouped":
gr = oseries.sort_index().reset_index().groupby(["x", "y"])
oseries = oseries.loc[gr["index"].first().tolist()]
self.add_labels(oseries, ax, adjust=adjust, **label_kwargs)

if backgroundmap:
self.add_background_map(ax)
Expand Down Expand Up @@ -1258,7 +1347,7 @@ def add_background_map(
ctx.add_basemap(ax, source=providers[map_provider], crs=proj.srs, **kwargs)

@staticmethod
def add_labels(df, ax, adjust=False, **kwargs):
def add_labels(df, ax, adjust=False, objects=None, **kwargs):
"""Add labels to points on plot.
Uses dataframe index to label points.
Expand All @@ -1271,11 +1360,12 @@ def add_labels(df, ax, adjust=False, **kwargs):
axes object to label points on
adjust: bool
automated smart label placement using adjustText
objects : list of matplotlib objects
use to avoid labels overlapping markers
**kwargs:
keyword arguments to ax.annotate
keyword arguments to ax.annotate or adjusttext
"""
stroke = [patheffects.withStroke(linewidth=3, foreground="w")]

fontsize = kwargs.pop("fontsize", 10)

if adjust:
Expand All @@ -1295,7 +1385,9 @@ def add_labels(df, ax, adjust=False, **kwargs):

adjust_text(
texts,
force_text=0.05,
objects=objects,
force_text=(0.05, 0.10),
**kwargs,
**{
"arrowprops": {
"arrowstyle": "-",
Expand All @@ -1318,4 +1410,5 @@ def add_labels(df, ax, adjust=False, **kwargs):
textcoords=textcoords,
xytext=xytext,
**{"path_effects": stroke},
**kwargs,
)
Loading

0 comments on commit 5debef8

Please sign in to comment.