Ridge plot
Plot histograms associated with tip trait values (ridge plot)¶
You can use the .hist()
or .fill()
functions of toytree to plot histograms. Here we will generate and plot a distribution of a data in order from top to bottom so that the histograms overlap in a "ridge plot" fashion. An analagous function in ggtree
seems to have merited an entire publication: https://academic.oup.com/mbe/article/35/12/3041/5142656.
In [3]:
Copied!
import toytree
import toyplot
import numpy as np
# we'll use scipy.stats to get prob. density func. of normal dist
import scipy.stats as sc
# generate a random tree with N tips
ntips = 40
tre = toytree.rtree.baltree(ntips)
# generate a distribution between -10 and 10 for each tip in the tree
points = np.linspace(-10, 10, 50)
dists = {}
for tip in tre.get_tip_labels():
dists[tip] = sc.norm.pdf(points, loc=np.random.randint(-5, 5, 1), scale=2)
import toytree
import toyplot
import numpy as np
# we'll use scipy.stats to get prob. density func. of normal dist
import scipy.stats as sc
# generate a random tree with N tips
ntips = 40
tre = toytree.rtree.baltree(ntips)
# generate a distribution between -10 and 10 for each tip in the tree
points = np.linspace(-10, 10, 50)
dists = {}
for tip in tre.get_tip_labels():
dists[tip] = sc.norm.pdf(points, loc=np.random.randint(-5, 5, 1), scale=2)
In [4]:
Copied!
# set up canvas for two panel plot
canvas = toyplot.Canvas(width=300, height=400)
# add tree to canvas
ax0 = canvas.cartesian(bounds=(50, 180, 50, 350), ymin=0, ymax=ntips, padding=15)
tre.draw(axes=ax0, tip_labels=False)
ax0.show = False
# add histograms to canvas
ax1 = canvas.cartesian(bounds=(200, 275, 50, 350), ymin=0, ymax=ntips, padding=15)
# iterate from top to bottom (ntips to 0)
for tip in range(tre.ntips)[::-1]:
# select a color for hist
color = "skyblue"
# get tip name and get hist from dict
tipname = tre.get_tip_labels()[tip]
probs = dists[tipname]
# fill histogram with slightly overlapping histograms
ax1.fill(
points, probs / probs.max() * 1.25,
baseline=[tip] * len(points),
style={"fill": color, "stroke": "white", "stroke-width": 0.5},
title=tipname,
)
# add horizontal line at base
ax1.hlines(tip, opacity=0.5, color="grey", style={"stroke-width": 0.5})
# hide y axis, show x
ax1.y.show = False
ax1.x.label.text = "Trait value"
ax1.x.ticks.show = True
# set up canvas for two panel plot
canvas = toyplot.Canvas(width=300, height=400)
# add tree to canvas
ax0 = canvas.cartesian(bounds=(50, 180, 50, 350), ymin=0, ymax=ntips, padding=15)
tre.draw(axes=ax0, tip_labels=False)
ax0.show = False
# add histograms to canvas
ax1 = canvas.cartesian(bounds=(200, 275, 50, 350), ymin=0, ymax=ntips, padding=15)
# iterate from top to bottom (ntips to 0)
for tip in range(tre.ntips)[::-1]:
# select a color for hist
color = "skyblue"
# get tip name and get hist from dict
tipname = tre.get_tip_labels()[tip]
probs = dists[tipname]
# fill histogram with slightly overlapping histograms
ax1.fill(
points, probs / probs.max() * 1.25,
baseline=[tip] * len(points),
style={"fill": color, "stroke": "white", "stroke-width": 0.5},
title=tipname,
)
# add horizontal line at base
ax1.hlines(tip, opacity=0.5, color="grey", style={"stroke-width": 0.5})
# hide y axis, show x
ax1.y.show = False
ax1.x.label.text = "Trait value"
ax1.x.ticks.show = True