Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ and this project adheres to [Semantic Versioning][].
### Changes

- `tl.rankby_obsm` now accepts `AnnData.obs` column names specified in the `obs_keys` argument.
-
- `pl.source_targets` now accepts extra arguments through `kw_scatter` and its `top` can be `None`, not displaying any label.

## 2.1.1

Expand Down
28 changes: 18 additions & 10 deletions src/decoupler/pl/_source_targets.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@ def source_targets(
x: str,
y: str,
name: str,
top: int = 5,
top: int | None = 5,
thr_x: float = 0.0,
thr_y: float = 0.0,
max_x: float | None = None,
max_y: float | None = None,
color_pos: str = "#D62728",
color_neg: str = "#1F77B4",
kw_scatter: dict | None = None,
**kwargs,
) -> None | Figure:
"""
Expand All @@ -38,7 +39,7 @@ def source_targets(
name
Name of the source to plot.
top
Number of top features based on the product of x and y to label.
Number of top features to show labels based on the product of x and y to label. Can be None.
thr_x
Value were to place a baseline for the x-axis.
thr_y
Expand All @@ -51,6 +52,8 @@ def source_targets(
Color to plot positively associated features.
color_neg
Color to plot negatively associated features.
kw_scatter
Keyword arguments passed to ``matplotlib.pyplot.scatter``.
%(plot)s

Example
Expand All @@ -72,7 +75,9 @@ def source_targets(
assert not pd.api.types.is_numeric_dtype(data.index), "data index must be features in net"
assert isinstance(net, pd.DataFrame), f"net must be a pd.DataFrame containing the columns {x} and {y}"
assert isinstance(name, str), "name must be a str"
assert isinstance(top, int) and top > 0, "top must be int and > 0"
if top is None:
top = 0
assert isinstance(top, int) and top >= 0, "top must be int and >= 0"
assert isinstance(thr_x, int | float), "thr_x must be numeric"
assert isinstance(thr_y, int | float), "thr_y must be numeric"
if max_x is None:
Expand All @@ -83,6 +88,8 @@ def source_targets(
assert isinstance(max_y, int | float) and max_y > 0, "max_y must be None, or numeric and > 0"
assert isinstance(color_pos, str), "color_pos must be str"
assert isinstance(color_neg, str), "color_neg must be str"
if kw_scatter is None:
kw_scatter = {}
# Instance
bp = Plotter(**kwargs)
# Extract df
Expand All @@ -101,7 +108,7 @@ def source_targets(
df["color"] = color_neg
df.loc[pos, "color"] = color_pos
# Plot
df.plot.scatter(x=x, y=y, c="color", ax=bp.ax)
df.plot.scatter(x=x, y=y, c="color", ax=bp.ax, **kw_scatter)
# Draw thr lines
bp.ax.axvline(x=thr_x, linestyle="--", color="black")
bp.ax.axhline(y=thr_y, linestyle="--", color="black")
Expand All @@ -112,10 +119,11 @@ def source_targets(
# Show top features
df["order"] = df[x].abs() * df[y].abs()
signs = df.sort_values("order", ascending=False)
signs = signs.iloc[:top]
texts = []
for tx, ty, ts in zip(signs[x], signs[y], signs.index, strict=False):
texts.append(bp.ax.text(tx, ty, ts))
if len(texts) > 0:
at.adjust_text(texts, arrowprops={"arrowstyle": "-", "color": "black"}, ax=bp.ax)
if top > 0:
signs = signs.iloc[:top]
texts = []
for tx, ty, ts in zip(signs[x], signs[y], signs.index, strict=False):
texts.append(bp.ax.text(tx, ty, ts))
if len(texts) > 0:
at.adjust_text(texts, arrowprops={"arrowstyle": "-", "color": "black"}, ax=bp.ax)
return bp._return()
15 changes: 15 additions & 0 deletions tests/pl/test_source_targets.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,21 @@ def test_source_targets(
fig = dc.pl.source_targets(data=deg, net=net, name=name, x="weight", y="stat", return_fig=True)
assert isinstance(fig, Figure)
plt.close(fig)
fig = dc.pl.source_targets(data=deg, net=net, top=None, name=name, x="weight", y="stat", return_fig=True)
assert isinstance(fig, Figure)
plt.close(fig)
fig = dc.pl.source_targets(
data=deg,
net=net,
top=None,
name=name,
x="weight",
y="stat",
return_fig=True,
kw_scatter={"alpha": 0.5, "s": 1},
)
assert isinstance(fig, Figure)
plt.close(fig)
else:
with pytest.raises(AssertionError):
dc.pl.source_targets(data=deg, net=net, name=name, x="weight", y="stat", return_fig=True)
Loading