Phylogenetic Tree
In [1]:
Copied!
# %pip install pycirclizely
# %pip install pycirclizely
In [2]:
Copied!
import plotly.io as pio
from IPython.display import HTML
import plotly.io as pio
from IPython.display import HTML
1. Simple Tree¶
User can plot the phylogenetic tree with Circos.initialize_from_tree()
or track.tree()
methods.
Both methods return a TreeViz instance, which can be manipulated to set phylogenetic tree
annotations such as marker and highlight.
1-1. Default Style¶
In [3]:
Copied!
from pycirclizely import Circos
from pycirclizely.utils import load_example_tree_file
tree_file = load_example_tree_file("alphabet.nwk")
circos, tv = Circos.initialize_from_tree(tree_file)
fig = circos.plotfig()
HTML(pio.to_html(fig, include_plotlyjs="cdn"))
from pycirclizely import Circos
from pycirclizely.utils import load_example_tree_file
tree_file = load_example_tree_file("alphabet.nwk")
circos, tv = Circos.initialize_from_tree(tree_file)
fig = circos.plotfig()
HTML(pio.to_html(fig, include_plotlyjs="cdn"))
Out[3]:
1-2. Change Style 1¶
In [4]:
Copied!
from pycirclizely import Circos
from pycirclizely.utils import load_example_tree_file
tree_file = load_example_tree_file("alphabet.nwk")
circos, tv = Circos.initialize_from_tree(
tree_file,
start=20, # Default: 0
end=340, # Default: 360
r_lim=(10, 100), # Default: (50, 100)
line_kws=dict(
line=dict(color="red", width=2)
), # Default: {}, Change color & linewidth
align_line_kws=dict(
line=dict(dash="dashdot", width=1),
), # Default: {}, Change linestyle & linewidth
)
fig = circos.plotfig()
HTML(pio.to_html(fig, include_plotlyjs="cdn"))
from pycirclizely import Circos
from pycirclizely.utils import load_example_tree_file
tree_file = load_example_tree_file("alphabet.nwk")
circos, tv = Circos.initialize_from_tree(
tree_file,
start=20, # Default: 0
end=340, # Default: 360
r_lim=(10, 100), # Default: (50, 100)
line_kws=dict(
line=dict(color="red", width=2)
), # Default: {}, Change color & linewidth
align_line_kws=dict(
line=dict(dash="dashdot", width=1),
), # Default: {}, Change linestyle & linewidth
)
fig = circos.plotfig()
HTML(pio.to_html(fig, include_plotlyjs="cdn"))
Out[4]:
1-3. Change Style 2¶
In [5]:
Copied!
from pycirclizely import Circos
from pycirclizely.utils import load_example_tree_file
# Define 4 types kwargs for `Circos.initialize_from_tree()` method
kwargs_list = [
dict(outer=True, align_leaf_label=True, ignore_branch_length=False),
dict(outer=True, align_leaf_label=False, ignore_branch_length=False),
dict(outer=False, align_leaf_label=True, ignore_branch_length=False),
dict(outer=True, align_leaf_label=True, ignore_branch_length=True),
]
# Plot trees with different kwargs
tree_file = load_example_tree_file("alphabet.nwk")
html_outputs = []
for kwargs in kwargs_list:
circos, tv = Circos.initialize_from_tree(
tree_file,
r_lim=(60, 100),
outer=kwargs["outer"],
align_leaf_label=kwargs["align_leaf_label"],
ignore_branch_length=kwargs["ignore_branch_length"],
)
kwargs_text = "<br>".join([f"{k}: {v}" for k, v in kwargs.items()])
circos.text(text=kwargs_text, font=dict(size=14))
fig = circos.plotfig()
html_outputs.append(HTML(pio.to_html(fig, include_plotlyjs="cdn")))
# Display all figures
for html in html_outputs:
display(html) # type: ignore[name-defined]
from pycirclizely import Circos
from pycirclizely.utils import load_example_tree_file
# Define 4 types kwargs for `Circos.initialize_from_tree()` method
kwargs_list = [
dict(outer=True, align_leaf_label=True, ignore_branch_length=False),
dict(outer=True, align_leaf_label=False, ignore_branch_length=False),
dict(outer=False, align_leaf_label=True, ignore_branch_length=False),
dict(outer=True, align_leaf_label=True, ignore_branch_length=True),
]
# Plot trees with different kwargs
tree_file = load_example_tree_file("alphabet.nwk")
html_outputs = []
for kwargs in kwargs_list:
circos, tv = Circos.initialize_from_tree(
tree_file,
r_lim=(60, 100),
outer=kwargs["outer"],
align_leaf_label=kwargs["align_leaf_label"],
ignore_branch_length=kwargs["ignore_branch_length"],
)
kwargs_text = "
".join([f"{k}: {v}" for k, v in kwargs.items()]) circos.text(text=kwargs_text, font=dict(size=14)) fig = circos.plotfig() html_outputs.append(HTML(pio.to_html(fig, include_plotlyjs="cdn"))) # Display all figures for html in html_outputs: display(html) # type: ignore[name-defined]
".join([f"{k}: {v}" for k, v in kwargs.items()]) circos.text(text=kwargs_text, font=dict(size=14)) fig = circos.plotfig() html_outputs.append(HTML(pio.to_html(fig, include_plotlyjs="cdn"))) # Display all figures for html in html_outputs: display(html) # type: ignore[name-defined]
1-4. Change Style 3¶
In [6]:
Copied!
from pycirclizely import Circos
from pycirclizely.utils import load_example_tree_file
# Define 4 types kwargs for `Circos.initialize_from_tree()` method
kwargs_list = [
dict(reverse=False, ladderize=False),
dict(reverse=True, ladderize=False),
dict(reverse=False, ladderize=True),
dict(reverse=True, ladderize=True),
]
# Plot trees with different kwargs
tree_file = load_example_tree_file("alphabet.nwk")
html_outputs = []
for kwargs in kwargs_list:
circos, tv = Circos.initialize_from_tree(
tree_file,
line_kws=dict(line=dict(width=1)),
reverse=kwargs["reverse"],
ladderize=kwargs["ladderize"],
)
kwargs_text = "<br>".join([f"{k}: {v}" for k, v in kwargs.items()])
circos.text(text=kwargs_text, font=dict(size=14))
fig = circos.plotfig()
html_outputs.append(HTML(pio.to_html(fig, include_plotlyjs="cdn")))
# Display all figures
for html in html_outputs:
display(html) # type: ignore[name-defined]
from pycirclizely import Circos
from pycirclizely.utils import load_example_tree_file
# Define 4 types kwargs for `Circos.initialize_from_tree()` method
kwargs_list = [
dict(reverse=False, ladderize=False),
dict(reverse=True, ladderize=False),
dict(reverse=False, ladderize=True),
dict(reverse=True, ladderize=True),
]
# Plot trees with different kwargs
tree_file = load_example_tree_file("alphabet.nwk")
html_outputs = []
for kwargs in kwargs_list:
circos, tv = Circos.initialize_from_tree(
tree_file,
line_kws=dict(line=dict(width=1)),
reverse=kwargs["reverse"],
ladderize=kwargs["ladderize"],
)
kwargs_text = "
".join([f"{k}: {v}" for k, v in kwargs.items()]) circos.text(text=kwargs_text, font=dict(size=14)) fig = circos.plotfig() html_outputs.append(HTML(pio.to_html(fig, include_plotlyjs="cdn"))) # Display all figures for html in html_outputs: display(html) # type: ignore[name-defined]
".join([f"{k}: {v}" for k, v in kwargs.items()]) circos.text(text=kwargs_text, font=dict(size=14)) fig = circos.plotfig() html_outputs.append(HTML(pio.to_html(fig, include_plotlyjs="cdn"))) # Display all figures for html in html_outputs: display(html) # type: ignore[name-defined]
1-5. Set Label Properties¶
In [7]:
Copied!
from pycirclizely import Circos
from pycirclizely.utils import ColorCycler, load_example_tree_file
tree_file = load_example_tree_file("alphabet.nwk")
circos, tv = Circos.initialize_from_tree(tree_file)
# Change label color
tv.set_node_label_props("A", font=dict(color="red", size=8))
# Change label color & size
tv.set_node_label_props("D", font=dict(color="blue", size=25))
# Hide label
tv.set_node_label_props("G", font=dict(size=0))
# Change label colors
color_cycler = ColorCycler("T10")
for name in list("MNOPQRSTUVWXY"):
tv.set_node_label_props(name, font=dict(color=color_cycler.get_color()))
# Add node info in hovertext
tv.show_node_info()
fig = circos.plotfig()
HTML(pio.to_html(fig, include_plotlyjs="cdn"))
from pycirclizely import Circos
from pycirclizely.utils import ColorCycler, load_example_tree_file
tree_file = load_example_tree_file("alphabet.nwk")
circos, tv = Circos.initialize_from_tree(tree_file)
# Change label color
tv.set_node_label_props("A", font=dict(color="red", size=8))
# Change label color & size
tv.set_node_label_props("D", font=dict(color="blue", size=25))
# Hide label
tv.set_node_label_props("G", font=dict(size=0))
# Change label colors
color_cycler = ColorCycler("T10")
for name in list("MNOPQRSTUVWXY"):
tv.set_node_label_props(name, font=dict(color=color_cycler.get_color()))
# Add node info in hovertext
tv.show_node_info()
fig = circos.plotfig()
HTML(pio.to_html(fig, include_plotlyjs="cdn"))
Out[7]:
1-6. Set Line Properties¶
In [8]:
Copied!
from pycirclizely import Circos
from pycirclizely.utils import load_example_tree_file
tree_file = load_example_tree_file("alphabet.nwk")
circos, tv = Circos.initialize_from_tree(tree_file, line_kws=dict(line=dict(width=1.0)))
# Change line color on [A,B,C,D,E,F] MRCA(Most Recent Common Ancestor)
# node and its descendent nodes
tv.set_node_line_props(["A", "B", "C", "D", "E", "F"], line=dict(color="red"))
# Change line color & width on [G,I] MRCA node and its descendent nodes
tv.set_node_line_props(["G", "I"], line=dict(color="blue", width=2.0))
# Change line color & label color on [M,W] MRCA node and its descendent nodes
tv.set_node_line_props(["M", "W"], apply_label_color=True, line=dict(color="green"))
# Change line color & label color on [R,T] MRCA node and its descendent nodes
tv.set_node_line_props(["R", "T"], apply_label_color=True, line=dict(color="purple"))
# Change line color & style [X,Y] MRCA node
tv.set_node_line_props(
["X", "Y"], descendent=False, line=dict(color="purple", dash="dot")
)
# Add node info in hovertext
tv.show_node_info()
fig = circos.plotfig()
HTML(pio.to_html(fig, include_plotlyjs="cdn"))
from pycirclizely import Circos
from pycirclizely.utils import load_example_tree_file
tree_file = load_example_tree_file("alphabet.nwk")
circos, tv = Circos.initialize_from_tree(tree_file, line_kws=dict(line=dict(width=1.0)))
# Change line color on [A,B,C,D,E,F] MRCA(Most Recent Common Ancestor)
# node and its descendent nodes
tv.set_node_line_props(["A", "B", "C", "D", "E", "F"], line=dict(color="red"))
# Change line color & width on [G,I] MRCA node and its descendent nodes
tv.set_node_line_props(["G", "I"], line=dict(color="blue", width=2.0))
# Change line color & label color on [M,W] MRCA node and its descendent nodes
tv.set_node_line_props(["M", "W"], apply_label_color=True, line=dict(color="green"))
# Change line color & label color on [R,T] MRCA node and its descendent nodes
tv.set_node_line_props(["R", "T"], apply_label_color=True, line=dict(color="purple"))
# Change line color & style [X,Y] MRCA node
tv.set_node_line_props(
["X", "Y"], descendent=False, line=dict(color="purple", dash="dot")
)
# Add node info in hovertext
tv.show_node_info()
fig = circos.plotfig()
HTML(pio.to_html(fig, include_plotlyjs="cdn"))
Out[8]:
1-7. Plot Marker¶
In [9]:
Copied!
from pycirclizely import Circos
from pycirclizely.utils import ColorCycler, load_example_tree_file
tree_file = load_example_tree_file("alphabet.nwk")
circos, tv = Circos.initialize_from_tree(tree_file)
# Plot markers on [A,B,C,D,E,F] MRCA(Most Recent Common Ancestor)
# node and its descendent nodes
tv.marker(["A", "B", "C", "D", "E", "F"], marker=dict(color="salmon", size=6))
# Plot square marker on [G,K] MRCA node
tv.marker(
["G", "K"],
descendent=False,
marker=dict(color="orange", symbol="square-dot", size=8),
)
# Plot star markers on [X,Y] MRCA node and its descendent nodes
tv.marker(["X", "Y"], marker=dict(color="lime", symbol="star", size=10))
# Plot colored markers on M,N,O,P,Q,R,S,T,U,V,W leaf nodes
color_cycler = ColorCycler("Set3")
for leaf_name in list("MNOPQRSTUVW"):
tv.marker(leaf_name, marker=dict(color=color_cycler.get_color(), size=10))
fig = circos.plotfig()
HTML(pio.to_html(fig, include_plotlyjs="cdn"))
from pycirclizely import Circos
from pycirclizely.utils import ColorCycler, load_example_tree_file
tree_file = load_example_tree_file("alphabet.nwk")
circos, tv = Circos.initialize_from_tree(tree_file)
# Plot markers on [A,B,C,D,E,F] MRCA(Most Recent Common Ancestor)
# node and its descendent nodes
tv.marker(["A", "B", "C", "D", "E", "F"], marker=dict(color="salmon", size=6))
# Plot square marker on [G,K] MRCA node
tv.marker(
["G", "K"],
descendent=False,
marker=dict(color="orange", symbol="square-dot", size=8),
)
# Plot star markers on [X,Y] MRCA node and its descendent nodes
tv.marker(["X", "Y"], marker=dict(color="lime", symbol="star", size=10))
# Plot colored markers on M,N,O,P,Q,R,S,T,U,V,W leaf nodes
color_cycler = ColorCycler("Set3")
for leaf_name in list("MNOPQRSTUVW"):
tv.marker(leaf_name, marker=dict(color=color_cycler.get_color(), size=10))
fig = circos.plotfig()
HTML(pio.to_html(fig, include_plotlyjs="cdn"))
Out[9]:
1-8. Plot Highlight¶
In [10]:
Copied!
from pycirclizely import Circos
from pycirclizely.utils import load_example_tree_file
tree_file = load_example_tree_file("alphabet.nwk")
circos, tv = Circos.initialize_from_tree(tree_file, line_kws=dict(line=dict(width=1)))
# Plot highlight on [A,B,C,D,E,F] MRCA(Most Recent Common Ancestor) node
tv.highlight(["A", "B", "C", "D", "E", "F"], fillcolor="salmon")
# Plot highlight on [G,K] MRCA node
tv.highlight(["G", "K"], fillcolor="orange")
# Plot highlight on L node with black thin dashdot edge line
tv.highlight("L", fillcolor="lime", line=dict(color="black", width=0.5, dash="dashdot"))
# Plot highlight on [N,W] MRCA node with low opacity and red edge line
tv.highlight(
["N", "W"], fillcolor="lightgrey", opacity=0.3, line=dict(color="red", width=0.5)
)
fig = circos.plotfig()
HTML(pio.to_html(fig, include_plotlyjs="cdn"))
from pycirclizely import Circos
from pycirclizely.utils import load_example_tree_file
tree_file = load_example_tree_file("alphabet.nwk")
circos, tv = Circos.initialize_from_tree(tree_file, line_kws=dict(line=dict(width=1)))
# Plot highlight on [A,B,C,D,E,F] MRCA(Most Recent Common Ancestor) node
tv.highlight(["A", "B", "C", "D", "E", "F"], fillcolor="salmon")
# Plot highlight on [G,K] MRCA node
tv.highlight(["G", "K"], fillcolor="orange")
# Plot highlight on L node with black thin dashdot edge line
tv.highlight("L", fillcolor="lime", line=dict(color="black", width=0.5, dash="dashdot"))
# Plot highlight on [N,W] MRCA node with low opacity and red edge line
tv.highlight(
["N", "W"], fillcolor="lightgrey", opacity=0.3, line=dict(color="red", width=0.5)
)
fig = circos.plotfig()
HTML(pio.to_html(fig, include_plotlyjs="cdn"))
Out[10]:
1-9. With Heatmap¶
In [11]:
Copied!
import numpy as np
from pycirclizely import Circos
from pycirclizely.utils import load_example_tree_file
np.random.seed(0)
tree_file = load_example_tree_file("alphabet.nwk")
circos, tv = Circos.initialize_from_tree(
tree_file,
r_lim=(30, 80),
# Set large margin to insert heatmap track between tree and labels
leaf_label_rmargin=24,
line_kws=dict(line=dict(width=1)),
)
# Plot heatmap
sector = tv.track.parent_sector
track = sector.add_track((80, 100))
track.axis(line=dict(color="grey"))
vmin, vmax, cmap = 0, 100, "RdBu_r"
data = np.random.randint(vmin, vmax + 1, (3, tv.leaf_num))
leaf_labels = tv.leaf_labels
custom_hover_text = [
f"""Leaf: {leaf_labels[col_idx]}
<br>Level: {row_idx + 1}
<br>Value: {data[row_idx, col_idx]}"""
for row_idx in range(data.shape[0])
for col_idx in range(data.shape[1])
]
coloraxis = circos.colorbar(vmin=vmin, vmax=vmax, cmap=cmap, orientation="h")
track.heatmap(
data, cmap=cmap, show_value=True, hover_text=custom_hover_text, coloraxis=coloraxis
)
fig = circos.plotfig()
HTML(pio.to_html(fig, include_plotlyjs="cdn"))
import numpy as np
from pycirclizely import Circos
from pycirclizely.utils import load_example_tree_file
np.random.seed(0)
tree_file = load_example_tree_file("alphabet.nwk")
circos, tv = Circos.initialize_from_tree(
tree_file,
r_lim=(30, 80),
# Set large margin to insert heatmap track between tree and labels
leaf_label_rmargin=24,
line_kws=dict(line=dict(width=1)),
)
# Plot heatmap
sector = tv.track.parent_sector
track = sector.add_track((80, 100))
track.axis(line=dict(color="grey"))
vmin, vmax, cmap = 0, 100, "RdBu_r"
data = np.random.randint(vmin, vmax + 1, (3, tv.leaf_num))
leaf_labels = tv.leaf_labels
custom_hover_text = [
f"""Leaf: {leaf_labels[col_idx]}
Level: {row_idx + 1}
Value: {data[row_idx, col_idx]}""" for row_idx in range(data.shape[0]) for col_idx in range(data.shape[1]) ] coloraxis = circos.colorbar(vmin=vmin, vmax=vmax, cmap=cmap, orientation="h") track.heatmap( data, cmap=cmap, show_value=True, hover_text=custom_hover_text, coloraxis=coloraxis ) fig = circos.plotfig() HTML(pio.to_html(fig, include_plotlyjs="cdn"))
Level: {row_idx + 1}
Value: {data[row_idx, col_idx]}""" for row_idx in range(data.shape[0]) for col_idx in range(data.shape[1]) ] coloraxis = circos.colorbar(vmin=vmin, vmax=vmax, cmap=cmap, orientation="h") track.heatmap( data, cmap=cmap, show_value=True, hover_text=custom_hover_text, coloraxis=coloraxis ) fig = circos.plotfig() HTML(pio.to_html(fig, include_plotlyjs="cdn"))
Out[11]:
1-10. With Heatmap + Bar¶
In [12]:
Copied!
import numpy as np
import pandas as pd
from pycirclizely import Circos
from pycirclizely.utils import load_example_tree_file
np.random.seed(0)
tree_file = load_example_tree_file("alphabet.nwk")
circos, tv = Circos.initialize_from_tree(
tree_file,
start=5,
end=355,
r_lim=(30, 70),
# Set large margin to insert heatmap & bar track between tree and labels
leaf_label_rmargin=34,
ignore_branch_length=True,
line_kws=dict(line=dict(width=1)),
)
leaf_labels = tv.leaf_labels
# Create example dataframe for heatmap & bar plot
df = pd.DataFrame(
dict(
s1=np.random.randint(0, 100, tv.leaf_num),
s2=np.random.randint(0, 100, tv.leaf_num),
s3=np.random.randint(0, 100, tv.leaf_num),
count=np.random.randint(1, 10, tv.leaf_num),
),
index=leaf_labels,
)
print(df.head())
# Plot bar (from `count` column data)
sector = tv.track.parent_sector
bar_track = sector.add_track((85, 100), r_pad_ratio=0.1)
bar_track.axis()
bar_track.grid()
x = np.arange(0, tv.leaf_num) + 0.5
y = df["count"].to_numpy()
custom_hover_text = [
f"Leaf: {leaf_labels[i]}<br>Count: {val}" for i, val in enumerate(y)
]
bar_track.bar(x, y, width=0.3, hover_text=custom_hover_text, fillcolor="orange")
# Plot heatmaps (from `s1, s2, s3` column data)
track1 = sector.add_track((80, 85))
custom_hover_text = [
f"Leaf: {leaf_labels[i]}<br>s1: {val}" for i, val in enumerate(df["s1"].to_numpy())
]
track1.heatmap(
df["s1"].to_numpy(),
cmap="Reds",
show_value=True,
hover_text=custom_hover_text,
rect_kws=dict(line=dict(color="grey", width=0.5)),
)
track2 = sector.add_track((75, 80))
custom_hover_text = [
f"Leaf: {leaf_labels[i]}<br>s2: {val}" for i, val in enumerate(df["s2"].to_numpy())
]
track2.heatmap(
df["s2"].to_numpy(),
cmap="Blues",
show_value=True,
hover_text=custom_hover_text,
rect_kws=dict(line=dict(color="grey", width=0.5)),
)
track3 = sector.add_track((70, 75))
custom_hover_text = [
f"Leaf: {leaf_labels[i]}<br>s3: {val}" for i, val in enumerate(df["s3"].to_numpy())
]
track3.heatmap(
df["s3"].to_numpy(),
cmap="Greens",
show_value=True,
hover_text=custom_hover_text,
rect_kws=dict(line=dict(color="grey", width=0.5)),
)
# Plot track labels
circos.text("count", r=bar_track.r_center, font=dict(color="orange"))
circos.text("s1", r=track1.r_center, font=dict(color="red"))
circos.text("s2", r=track2.r_center, font=dict(color="blue"))
circos.text("s3", r=track3.r_center, font=dict(color="green"))
fig = circos.plotfig()
HTML(pio.to_html(fig, include_plotlyjs="cdn"))
import numpy as np
import pandas as pd
from pycirclizely import Circos
from pycirclizely.utils import load_example_tree_file
np.random.seed(0)
tree_file = load_example_tree_file("alphabet.nwk")
circos, tv = Circos.initialize_from_tree(
tree_file,
start=5,
end=355,
r_lim=(30, 70),
# Set large margin to insert heatmap & bar track between tree and labels
leaf_label_rmargin=34,
ignore_branch_length=True,
line_kws=dict(line=dict(width=1)),
)
leaf_labels = tv.leaf_labels
# Create example dataframe for heatmap & bar plot
df = pd.DataFrame(
dict(
s1=np.random.randint(0, 100, tv.leaf_num),
s2=np.random.randint(0, 100, tv.leaf_num),
s3=np.random.randint(0, 100, tv.leaf_num),
count=np.random.randint(1, 10, tv.leaf_num),
),
index=leaf_labels,
)
print(df.head())
# Plot bar (from `count` column data)
sector = tv.track.parent_sector
bar_track = sector.add_track((85, 100), r_pad_ratio=0.1)
bar_track.axis()
bar_track.grid()
x = np.arange(0, tv.leaf_num) + 0.5
y = df["count"].to_numpy()
custom_hover_text = [
f"Leaf: {leaf_labels[i]}
Count: {val}" for i, val in enumerate(y) ] bar_track.bar(x, y, width=0.3, hover_text=custom_hover_text, fillcolor="orange") # Plot heatmaps (from `s1, s2, s3` column data) track1 = sector.add_track((80, 85)) custom_hover_text = [ f"Leaf: {leaf_labels[i]}
s1: {val}" for i, val in enumerate(df["s1"].to_numpy()) ] track1.heatmap( df["s1"].to_numpy(), cmap="Reds", show_value=True, hover_text=custom_hover_text, rect_kws=dict(line=dict(color="grey", width=0.5)), ) track2 = sector.add_track((75, 80)) custom_hover_text = [ f"Leaf: {leaf_labels[i]}
s2: {val}" for i, val in enumerate(df["s2"].to_numpy()) ] track2.heatmap( df["s2"].to_numpy(), cmap="Blues", show_value=True, hover_text=custom_hover_text, rect_kws=dict(line=dict(color="grey", width=0.5)), ) track3 = sector.add_track((70, 75)) custom_hover_text = [ f"Leaf: {leaf_labels[i]}
s3: {val}" for i, val in enumerate(df["s3"].to_numpy()) ] track3.heatmap( df["s3"].to_numpy(), cmap="Greens", show_value=True, hover_text=custom_hover_text, rect_kws=dict(line=dict(color="grey", width=0.5)), ) # Plot track labels circos.text("count", r=bar_track.r_center, font=dict(color="orange")) circos.text("s1", r=track1.r_center, font=dict(color="red")) circos.text("s2", r=track2.r_center, font=dict(color="blue")) circos.text("s3", r=track3.r_center, font=dict(color="green")) fig = circos.plotfig() HTML(pio.to_html(fig, include_plotlyjs="cdn"))
Count: {val}" for i, val in enumerate(y) ] bar_track.bar(x, y, width=0.3, hover_text=custom_hover_text, fillcolor="orange") # Plot heatmaps (from `s1, s2, s3` column data) track1 = sector.add_track((80, 85)) custom_hover_text = [ f"Leaf: {leaf_labels[i]}
s1: {val}" for i, val in enumerate(df["s1"].to_numpy()) ] track1.heatmap( df["s1"].to_numpy(), cmap="Reds", show_value=True, hover_text=custom_hover_text, rect_kws=dict(line=dict(color="grey", width=0.5)), ) track2 = sector.add_track((75, 80)) custom_hover_text = [ f"Leaf: {leaf_labels[i]}
s2: {val}" for i, val in enumerate(df["s2"].to_numpy()) ] track2.heatmap( df["s2"].to_numpy(), cmap="Blues", show_value=True, hover_text=custom_hover_text, rect_kws=dict(line=dict(color="grey", width=0.5)), ) track3 = sector.add_track((70, 75)) custom_hover_text = [ f"Leaf: {leaf_labels[i]}
s3: {val}" for i, val in enumerate(df["s3"].to_numpy()) ] track3.heatmap( df["s3"].to_numpy(), cmap="Greens", show_value=True, hover_text=custom_hover_text, rect_kws=dict(line=dict(color="grey", width=0.5)), ) # Plot track labels circos.text("count", r=bar_track.r_center, font=dict(color="orange")) circos.text("s1", r=track1.r_center, font=dict(color="red")) circos.text("s2", r=track2.r_center, font=dict(color="blue")) circos.text("s3", r=track3.r_center, font=dict(color="green")) fig = circos.plotfig() HTML(pio.to_html(fig, include_plotlyjs="cdn"))
s1 s2 s3 count A 44 20 28 6 B 47 80 34 5 C 64 69 0 5 D 67 79 0 7 E 67 47 36 5
Out[12]:
2-1. Default Style¶
In [13]:
Copied!
from pycirclizely import Circos
from pycirclizely.utils import load_example_tree_file
tree_file = load_example_tree_file("large_example.nwk")
circos, tv = Circos.initialize_from_tree(tree_file, leaf_label_size=5)
fig = circos.plotfig()
HTML(pio.to_html(fig, include_plotlyjs="cdn"))
from pycirclizely import Circos
from pycirclizely.utils import load_example_tree_file
tree_file = load_example_tree_file("large_example.nwk")
circos, tv = Circos.initialize_from_tree(tree_file, leaf_label_size=5)
fig = circos.plotfig()
HTML(pio.to_html(fig, include_plotlyjs="cdn"))
Out[13]:
2-2. Coloring Style¶
The legend is added with a dummy scatter. TODO Modify tree.py so instead of a shape simpleline a trace is drawed, with the legend associated.
In [14]:
Copied!
import plotly.graph_objects as go
from pycirclizely import Circos
from pycirclizely.utils import ColorCycler, load_example_tree_file
tree_file = load_example_tree_file("large_example.nwk")
circos, tv = Circos.initialize_from_tree(
tree_file,
start=-90,
end=270,
r_lim=(30, 100),
leaf_label_size=5,
ignore_branch_length=True,
label_formatter=lambda t: t.replace("_", " "),
)
# Define group-species dict for tree annotation
# In this example, set minimum species list to specify group's MRCA node
group_name2species_list = dict(
Monotremata=["Tachyglossus_aculeatus", "Ornithorhynchus_anatinus"],
Marsupialia=["Monodelphis_domestica", "Vombatus_ursinus"],
Xenarthra=["Choloepus_didactylus", "Dasypus_novemcinctus"],
Afrotheria=["Trichechus_manatus", "Chrysochloris_asiatica"],
Euarchontes=["Galeopterus_variegatus", "Theropithecus_gelada"],
Glires=["Oryctolagus_cuniculus", "Microtus_oregoni"],
Laurasiatheria=["Talpa_occidentalis", "Mirounga_leonina"],
)
# Set tree line color & label color
color_cycler = ColorCycler("T10")
group_name2color = {
name: color_cycler.get_color() for name in group_name2species_list.keys()
}
for group_name, species_list in group_name2species_list.items():
color = group_name2color[group_name]
tv.set_node_line_props(species_list, apply_label_color=True, line=dict(color=color))
# Plot figure & set legend on center
fig = circos.plotfig()
for group_name, color in group_name2color.items():
# Use a dummy trace to create a legend entry
fig.add_trace(
go.Scatter(
x=[None],
y=None,
mode="markers",
marker=dict(color=color, size=10),
name=group_name,
showlegend=True,
)
)
fig.update_layout(
legend=dict(
x=0.5,
y=0.47,
xanchor="center",
yanchor="middle",
font=dict(size=10),
bgcolor="rgba(255,255,255,0.0)",
)
)
HTML(pio.to_html(fig, include_plotlyjs="cdn"))
import plotly.graph_objects as go
from pycirclizely import Circos
from pycirclizely.utils import ColorCycler, load_example_tree_file
tree_file = load_example_tree_file("large_example.nwk")
circos, tv = Circos.initialize_from_tree(
tree_file,
start=-90,
end=270,
r_lim=(30, 100),
leaf_label_size=5,
ignore_branch_length=True,
label_formatter=lambda t: t.replace("_", " "),
)
# Define group-species dict for tree annotation
# In this example, set minimum species list to specify group's MRCA node
group_name2species_list = dict(
Monotremata=["Tachyglossus_aculeatus", "Ornithorhynchus_anatinus"],
Marsupialia=["Monodelphis_domestica", "Vombatus_ursinus"],
Xenarthra=["Choloepus_didactylus", "Dasypus_novemcinctus"],
Afrotheria=["Trichechus_manatus", "Chrysochloris_asiatica"],
Euarchontes=["Galeopterus_variegatus", "Theropithecus_gelada"],
Glires=["Oryctolagus_cuniculus", "Microtus_oregoni"],
Laurasiatheria=["Talpa_occidentalis", "Mirounga_leonina"],
)
# Set tree line color & label color
color_cycler = ColorCycler("T10")
group_name2color = {
name: color_cycler.get_color() for name in group_name2species_list.keys()
}
for group_name, species_list in group_name2species_list.items():
color = group_name2color[group_name]
tv.set_node_line_props(species_list, apply_label_color=True, line=dict(color=color))
# Plot figure & set legend on center
fig = circos.plotfig()
for group_name, color in group_name2color.items():
# Use a dummy trace to create a legend entry
fig.add_trace(
go.Scatter(
x=[None],
y=None,
mode="markers",
marker=dict(color=color, size=10),
name=group_name,
showlegend=True,
)
)
fig.update_layout(
legend=dict(
x=0.5,
y=0.47,
xanchor="center",
yanchor="middle",
font=dict(size=10),
bgcolor="rgba(255,255,255,0.0)",
)
)
HTML(pio.to_html(fig, include_plotlyjs="cdn"))
Out[14]:
2-3. With Heatmap¶
In [15]:
Copied!
import numpy as np
from pycirclizely import Circos
from pycirclizely.utils import ColorCycler, load_example_tree_file
np.random.seed(0)
tree_file = load_example_tree_file("large_example.nwk")
circos, tv = Circos.initialize_from_tree(
tree_file,
start=-350,
end=0,
r_lim=(10, 80),
leaf_label_size=5,
leaf_label_rmargin=23,
line_kws=dict(line=dict(color="lightgrey", width=1.5)),
)
leaf_labels = tv.leaf_labels
# Define group-species dict for tree annotation
# In this example, set minimum species list to specify group's MRCA node
group_name2species_list = dict(
Monotremata=["Tachyglossus_aculeatus", "Ornithorhynchus_anatinus"],
Marsupialia=["Monodelphis_domestica", "Vombatus_ursinus"],
Xenarthra=["Choloepus_didactylus", "Dasypus_novemcinctus"],
Afrotheria=["Trichechus_manatus", "Chrysochloris_asiatica"],
Euarchontes=["Galeopterus_variegatus", "Theropithecus_gelada"],
Glires=["Oryctolagus_cuniculus", "Microtus_oregoni"],
Laurasiatheria=["Talpa_occidentalis", "Mirounga_leonina"],
)
# Set tree line color
color_cycler = ColorCycler("Set2")
for species_list in group_name2species_list.values():
tv.set_node_line_props(species_list, line=dict(color=color_cycler.get_color()))
# Plot heatmap
sector = circos.sectors[0]
heatmap_track = sector.add_track((80, 100))
matrix_data = np.random.randint(0, 100, (5, tv.leaf_num))
levels = list("EDCBA")
custom_hover_text = [
f"""Leaf: {leaf_labels[col_idx]}
<br>Level: {levels[row_idx]}
<br>Value: {matrix_data[row_idx, col_idx]}"""
for row_idx in range(matrix_data.shape[0])
for col_idx in range(matrix_data.shape[1])
]
heatmap_track.heatmap(matrix_data, cmap="viridis", hover_text=custom_hover_text)
heatmap_track.yticks(
[0.5, 1.5, 2.5, 3.5, 4.5],
levels,
vmax=5,
tick_length=0,
text_kws=dict(font=dict(size=10)),
)
fig = circos.plotfig()
HTML(pio.to_html(fig, include_plotlyjs="cdn"))
import numpy as np
from pycirclizely import Circos
from pycirclizely.utils import ColorCycler, load_example_tree_file
np.random.seed(0)
tree_file = load_example_tree_file("large_example.nwk")
circos, tv = Circos.initialize_from_tree(
tree_file,
start=-350,
end=0,
r_lim=(10, 80),
leaf_label_size=5,
leaf_label_rmargin=23,
line_kws=dict(line=dict(color="lightgrey", width=1.5)),
)
leaf_labels = tv.leaf_labels
# Define group-species dict for tree annotation
# In this example, set minimum species list to specify group's MRCA node
group_name2species_list = dict(
Monotremata=["Tachyglossus_aculeatus", "Ornithorhynchus_anatinus"],
Marsupialia=["Monodelphis_domestica", "Vombatus_ursinus"],
Xenarthra=["Choloepus_didactylus", "Dasypus_novemcinctus"],
Afrotheria=["Trichechus_manatus", "Chrysochloris_asiatica"],
Euarchontes=["Galeopterus_variegatus", "Theropithecus_gelada"],
Glires=["Oryctolagus_cuniculus", "Microtus_oregoni"],
Laurasiatheria=["Talpa_occidentalis", "Mirounga_leonina"],
)
# Set tree line color
color_cycler = ColorCycler("Set2")
for species_list in group_name2species_list.values():
tv.set_node_line_props(species_list, line=dict(color=color_cycler.get_color()))
# Plot heatmap
sector = circos.sectors[0]
heatmap_track = sector.add_track((80, 100))
matrix_data = np.random.randint(0, 100, (5, tv.leaf_num))
levels = list("EDCBA")
custom_hover_text = [
f"""Leaf: {leaf_labels[col_idx]}
Level: {levels[row_idx]}
Value: {matrix_data[row_idx, col_idx]}""" for row_idx in range(matrix_data.shape[0]) for col_idx in range(matrix_data.shape[1]) ] heatmap_track.heatmap(matrix_data, cmap="viridis", hover_text=custom_hover_text) heatmap_track.yticks( [0.5, 1.5, 2.5, 3.5, 4.5], levels, vmax=5, tick_length=0, text_kws=dict(font=dict(size=10)), ) fig = circos.plotfig() HTML(pio.to_html(fig, include_plotlyjs="cdn"))
Level: {levels[row_idx]}
Value: {matrix_data[row_idx, col_idx]}""" for row_idx in range(matrix_data.shape[0]) for col_idx in range(matrix_data.shape[1]) ] heatmap_track.heatmap(matrix_data, cmap="viridis", hover_text=custom_hover_text) heatmap_track.yticks( [0.5, 1.5, 2.5, 3.5, 4.5], levels, vmax=5, tick_length=0, text_kws=dict(font=dict(size=10)), ) fig = circos.plotfig() HTML(pio.to_html(fig, include_plotlyjs="cdn"))
Out[15]:
2-4. With Complex Heatmap¶
In [16]:
Copied!
import numpy as np
import pandas as pd
from pycirclizely import Circos
from pycirclizely.utils import load_example_tree_file
np.random.seed(0)
tree_file = load_example_tree_file("large_example.nwk")
circos, tv = Circos.initialize_from_tree(
tree_file,
start=-355,
end=-5,
r_lim=(10, 80),
leaf_label_size=0,
)
tv.track.axis(fillcolor="lightgrey", line=dict(color="lightgrey"), opacity=0.2)
# Create example dataframe for heatmap plot
heatmap_df = pd.DataFrame(
dict(
A=np.random.randint(0, 100, tv.leaf_num),
B=np.random.randint(0, 100, tv.leaf_num),
C=np.random.randint(0, 2, tv.leaf_num),
D=np.random.randint(0, 2, tv.leaf_num).astype(bool),
),
index=tv.leaf_labels,
)
print(heatmap_df)
# Plot heatmap with various style
sector = circos.sectors[0]
sector.rect(r_lim=(80, 100), line=dict(color="grey", width=1))
heatmap_track1 = sector.add_track((95, 100))
heatmap_track1.heatmap(
heatmap_df["A"].to_numpy(),
cmap="Reds",
vmin=0,
vmax=100,
show_value=True,
hover_text=None,
text_kws=dict(font=dict(size=5), orientation="vertical"),
)
circos.text("A", r=heatmap_track1.r_center, font=dict(size=12, color="red"))
heatmap_track2 = sector.add_track((90, 95))
heatmap_track2.heatmap(
heatmap_df["B"].to_numpy(), cmap="Blues", vmin=0, vmax=100, hover_text=None
)
circos.text("B", r=heatmap_track2.r_center, font=dict(size=12, color="blue"))
heatmap_track3 = sector.add_track((85, 90))
lime_cmap = [(0.0, "white"), (1.0, "lime")]
heatmap_track3.heatmap(
heatmap_df["C"].to_numpy(),
cmap=lime_cmap,
vmin=0,
vmax=1,
show_value=True,
hover_text=None,
text_kws=dict(font=dict(size=5)),
rect_kws=dict(line=dict(color="lightgrey", width=0.5)),
)
circos.text("C", r=heatmap_track3.r_center, font=dict(size=12, color="lime"))
heatmap_track4 = sector.add_track((80, 85))
orange_cmap = [(0.0, "white"), (1.0, "orange")]
heatmap_track4.heatmap(
heatmap_df["D"].to_numpy(),
cmap=orange_cmap,
vmin=0,
vmax=1,
hover_text=None,
rect_kws=dict(line=dict(color="lightgrey", width=0.5)),
)
circos.text("D", r=heatmap_track4.r_center, font=dict(size=12, color="orange"))
fig = circos.plotfig()
HTML(pio.to_html(fig, include_plotlyjs="cdn"))
import numpy as np
import pandas as pd
from pycirclizely import Circos
from pycirclizely.utils import load_example_tree_file
np.random.seed(0)
tree_file = load_example_tree_file("large_example.nwk")
circos, tv = Circos.initialize_from_tree(
tree_file,
start=-355,
end=-5,
r_lim=(10, 80),
leaf_label_size=0,
)
tv.track.axis(fillcolor="lightgrey", line=dict(color="lightgrey"), opacity=0.2)
# Create example dataframe for heatmap plot
heatmap_df = pd.DataFrame(
dict(
A=np.random.randint(0, 100, tv.leaf_num),
B=np.random.randint(0, 100, tv.leaf_num),
C=np.random.randint(0, 2, tv.leaf_num),
D=np.random.randint(0, 2, tv.leaf_num).astype(bool),
),
index=tv.leaf_labels,
)
print(heatmap_df)
# Plot heatmap with various style
sector = circos.sectors[0]
sector.rect(r_lim=(80, 100), line=dict(color="grey", width=1))
heatmap_track1 = sector.add_track((95, 100))
heatmap_track1.heatmap(
heatmap_df["A"].to_numpy(),
cmap="Reds",
vmin=0,
vmax=100,
show_value=True,
hover_text=None,
text_kws=dict(font=dict(size=5), orientation="vertical"),
)
circos.text("A", r=heatmap_track1.r_center, font=dict(size=12, color="red"))
heatmap_track2 = sector.add_track((90, 95))
heatmap_track2.heatmap(
heatmap_df["B"].to_numpy(), cmap="Blues", vmin=0, vmax=100, hover_text=None
)
circos.text("B", r=heatmap_track2.r_center, font=dict(size=12, color="blue"))
heatmap_track3 = sector.add_track((85, 90))
lime_cmap = [(0.0, "white"), (1.0, "lime")]
heatmap_track3.heatmap(
heatmap_df["C"].to_numpy(),
cmap=lime_cmap,
vmin=0,
vmax=1,
show_value=True,
hover_text=None,
text_kws=dict(font=dict(size=5)),
rect_kws=dict(line=dict(color="lightgrey", width=0.5)),
)
circos.text("C", r=heatmap_track3.r_center, font=dict(size=12, color="lime"))
heatmap_track4 = sector.add_track((80, 85))
orange_cmap = [(0.0, "white"), (1.0, "orange")]
heatmap_track4.heatmap(
heatmap_df["D"].to_numpy(),
cmap=orange_cmap,
vmin=0,
vmax=1,
hover_text=None,
rect_kws=dict(line=dict(color="lightgrey", width=0.5)),
)
circos.text("D", r=heatmap_track4.r_center, font=dict(size=12, color="orange"))
fig = circos.plotfig()
HTML(pio.to_html(fig, include_plotlyjs="cdn"))
A B C D Tachyglossus_aculeatus 44 21 0 False Ornithorhynchus_anatinus 47 25 1 True Monodelphis_domestica 64 80 1 True Gracilinanus_agilis 67 60 1 True Dromiciops_gliroides 67 61 1 False ... .. .. .. ... Halichoerus_grypus 75 72 1 True Neomonachus_schauinslandi 56 61 1 True Leptonychotes_weddellii 16 13 0 True Mirounga_leonina 24 5 1 True Mirounga_angustirostris 29 0 0 False [190 rows x 4 columns]
Out[16]:
3. Multiple Trees¶
3-1. Default Style¶
In [17]:
Copied!
import random
from Bio.Phylo.BaseTree import Tree
from pycirclizely import Circos
random.seed(0)
# Create 3 randomized trees
tree_size_list = [60, 40, 50]
trees = [Tree.randomized(size, branch_stdev=0.5) for size in tree_size_list]
# Initialize circos sector with 3 randomized tree size
sectors = {name: tree.count_terminals() for name, tree in zip(list("ABC"), trees)}
circos = Circos(sectors, space=5)
for sector, tree in zip(circos.sectors, trees):
sector.text(f"{sector.name} ({sector.size})", r=120, font=dict(size=14))
track = sector.add_track((30, 100))
track.tree(tree, leaf_label_size=8)
fig = circos.plotfig()
HTML(pio.to_html(fig, include_plotlyjs="cdn"))
import random
from Bio.Phylo.BaseTree import Tree
from pycirclizely import Circos
random.seed(0)
# Create 3 randomized trees
tree_size_list = [60, 40, 50]
trees = [Tree.randomized(size, branch_stdev=0.5) for size in tree_size_list]
# Initialize circos sector with 3 randomized tree size
sectors = {name: tree.count_terminals() for name, tree in zip(list("ABC"), trees)}
circos = Circos(sectors, space=5)
for sector, tree in zip(circos.sectors, trees):
sector.text(f"{sector.name} ({sector.size})", r=120, font=dict(size=14))
track = sector.add_track((30, 100))
track.tree(tree, leaf_label_size=8)
fig = circos.plotfig()
HTML(pio.to_html(fig, include_plotlyjs="cdn"))
Out[17]:
3-2. With Heatmap + Bar¶
In [18]:
Copied!
import random
import numpy as np
from Bio.Phylo.BaseTree import Tree
from pycirclizely import Circos
random.seed(0)
np.random.seed(0)
# Create 3 randomized trees
tree_size_list = [60, 40, 50]
trees = [Tree.randomized(size, branch_stdev=0.5) for size in tree_size_list]
# Initialize circos sector with 3 randomized tree size
sectors = {name: tree.count_terminals() for name, tree in zip(list("ABC"), trees)}
circos = Circos(sectors, space=5)
colors = ["tomato", "skyblue", "limegreen"]
cmaps = ["RdBu_r", "viridis", "Spectral"]
for sector, tree, color, cmap in zip(circos.sectors, trees, colors, cmaps): # type: ignore[assignment]
sector.text(f"{sector.name} ({sector.size})", font=dict(size=12))
# Plot randomized tree
tree_track = sector.add_track((30, 70))
tree_track.axis(fillcolor=color, opacity=0.2)
tree_track.tree(tree, leaf_label_size=0)
# Plot randomized heatmap
heatmap_track = sector.add_track((70, 85))
matrix_data = np.random.randint(0, 100, (5, int(sector.size)))
heatmap_track.axis(line=dict(color="grey"))
heatmap_track.heatmap(matrix_data, cmap=cmap)
# Plot randomized bar
bar_track = sector.add_track((85, 100))
x = np.arange(0, int(sector.size)) + 0.5
height = np.random.randint(1, 10, int(sector.size))
bar_track.bar(x, height, fillcolor=color, line=dict(color="grey", width=0.5))
fig = circos.plotfig()
HTML(pio.to_html(fig, include_plotlyjs="cdn"))
import random
import numpy as np
from Bio.Phylo.BaseTree import Tree
from pycirclizely import Circos
random.seed(0)
np.random.seed(0)
# Create 3 randomized trees
tree_size_list = [60, 40, 50]
trees = [Tree.randomized(size, branch_stdev=0.5) for size in tree_size_list]
# Initialize circos sector with 3 randomized tree size
sectors = {name: tree.count_terminals() for name, tree in zip(list("ABC"), trees)}
circos = Circos(sectors, space=5)
colors = ["tomato", "skyblue", "limegreen"]
cmaps = ["RdBu_r", "viridis", "Spectral"]
for sector, tree, color, cmap in zip(circos.sectors, trees, colors, cmaps): # type: ignore[assignment]
sector.text(f"{sector.name} ({sector.size})", font=dict(size=12))
# Plot randomized tree
tree_track = sector.add_track((30, 70))
tree_track.axis(fillcolor=color, opacity=0.2)
tree_track.tree(tree, leaf_label_size=0)
# Plot randomized heatmap
heatmap_track = sector.add_track((70, 85))
matrix_data = np.random.randint(0, 100, (5, int(sector.size)))
heatmap_track.axis(line=dict(color="grey"))
heatmap_track.heatmap(matrix_data, cmap=cmap)
# Plot randomized bar
bar_track = sector.add_track((85, 100))
x = np.arange(0, int(sector.size)) + 0.5
height = np.random.randint(1, 10, int(sector.size))
bar_track.bar(x, height, fillcolor=color, line=dict(color="grey", width=0.5))
fig = circos.plotfig()
HTML(pio.to_html(fig, include_plotlyjs="cdn"))
Out[18]:
In [ ]:
Copied!