@@ -162,6 +162,7 @@ svg_string = ts_tiny.draw_svg(
162162 size=svg_size,
163163 y_axis=True, y_label=" ", # optional: show a time scale on the left
164164 time_scale="rank", x_scale="treewise", # Force same axis settings as the text view
165+ title="A basic SVG plot",
165166)
166167display(svg_string) # If the last line in a cell, wrapping this in display() is not needed
167168```
@@ -201,14 +202,18 @@ with 8 samples, but where we've restricted the amount of the tree sequence we pl
201202``` {code-cell} ipython3
202203x_limits = [5000, 15000]
203204# Create evenly-spaced y tick positions to avoid overlap
204- y_tick_pos = [0, 1000, 2000, 3000, 4000 ]
205+ y_tick_pos = [0, 1000, 2000, 3000]
205206
206- print("The tree sequence between positions {} and {} ...".format(*x_limits))
207- display(ts_small.draw_svg(y_axis=True, y_ticks=y_tick_pos, x_lim=x_limits))
207+ display(ts_small.draw_svg(
208+ size=svg_size,
209+ y_axis=True,
210+ y_ticks=y_tick_pos,
211+ x_lim=x_limits,
212+ title="The tree sequence between positions {} and {}".format(*x_limits)
213+ ))
208214
209215third_tree = ts_small.at_index(2)
210- print("... or just look at (say) the third tree")
211- display(third_tree.draw_svg())
216+ display(third_tree.draw_svg(title="A plot of the third tree"))
212217```
213218
214219As the number of sample nodes increases, internal nodes often bunch up at recent time
@@ -225,20 +230,21 @@ styling is detailed {ref}`later in this tutorial <sec_tskit_viz_styling>`).
225230(sec_tskit_viz_large_tree_sequence)=
226231
227232``` {code-cell} ipython3
228- print("A larger tree, on a log timescale")
229233wide_fmt = (1200, 250)
230234# Create a stylesheet that shrinks labels and rotates leaf labels, to avoid overlap
231235node_label_style = (
232236 ".node > .lab {font-size: 80%}"
233237 ".leaf > .lab {text-anchor: start; transform: rotate(90deg) translate(6px)}"
234238)
239+
235240ts_full.first().draw_svg(
236241 size=wide_fmt,
237242 time_scale="log_time",
238243 y_gridlines=True,
239244 y_axis=True,
240245 y_ticks=[1, 10, 100, 1000],
241- style=node_label_style,
246+ style=node_label_style + "svg > .title text {font-size: 150%}",
247+ title="A larger tree, on a log timescale",
242248)
243249```
244250
@@ -290,9 +296,11 @@ plot region, or simply plotting the tree itself:
290296
291297
292298``` {code-cell} ipython3
293- third_tree = ts_mutated.at_index(2)
294- print(f"The third tree in the mutated tree sequence, which covers {third_tree.interval}")
295- third_tree.draw_svg(size=(200, 300))
299+ tree3 = ts_mutated.at_index(2)
300+ tree3.draw_svg(
301+ size=(320, 300),
302+ title=f"3rd tree, from position {int(tree3.interval.left)} to {int(tree3.interval.right)}",
303+ )
296304```
297305
298306(sec_tskit_viz_extra_mutations)=
@@ -308,7 +316,11 @@ associated with an edge in the tree but which fall outside the interval of that
308316default these mutations are drawn in a slightly different shade (e.g. mutation 64 below).
309317
310318``` {code-cell} ipython3
311- third_tree.draw_svg(size=(200, 300), all_edge_mutations=True)
319+ tree3.draw_svg(
320+ size=(320, 300),
321+ all_edge_mutations=True,
322+ title="As above, but with all mutations on visible edges"
323+ )
312324```
313325
314326(sec_tskit_viz_labelling)=
@@ -337,6 +349,7 @@ for mut in ts_mutated.mutations(): # Make pretty labels showing the change in s
337349 mut_labels[mut.id] = f"{prev}→{mut.derived_state}"
338350
339351ts_mutated.draw_svg(
352+ size=(1000, 300),
340353 y_axis=True, y_ticks=y_tick_pos, x_lim=x_limits,
341354 node_labels=nd_labels,
342355 mutation_labels=mut_labels,
@@ -1064,6 +1077,43 @@ means that there can be sample nodes which are "isolated" in a tree. These are d
10641077unconnected to the main topology in one or more trees (e.g. nodes 7 and 8 above).
10651078:::
10661079
1080+ #### Adding imagery
1081+
1082+ The ` preamble ` argument allows arbitrary SVG commands to be included in an SVG plot.
1083+ This can be used, for instance, to annotate parts of the plot or construct legends:
1084+
1085+ ``` {code-cell} ipython3
1086+ :"tags": ["hide-input"]
1087+ ts = tskit.load("data/viz_ts_full.trees")
1088+
1089+ styles = [
1090+ f".node.p{p.id} > .sym " + "{" + f"fill: {colour}" + "}"
1091+ for colour, p in zip(['red', 'green', 'blue'], ts_full.populations())
1092+ ] # styles created as in previous examples
1093+
1094+ # Make a legend: first create a surrounding box and a title
1095+ legend = '<rect width="145" height="75" x="2" y="10" fill="#EEE" stroke="grey" />'
1096+ legend += '<text x="65" y="25" font-weight="bold">Key</text>'
1097+ # Now make the legend lines, one for each population. Setting classes that match those
1098+ # used for normal nodes means that styled colours are automatically picked-up.
1099+ legend += "".join([
1100+ f'<g transform="translate(5, {40 + 15*p.id})" class="node p{p.id}">' # an SVG group
1101+ f'<rect width="6" height="6" class="sym" />' # Square symbol
1102+ f'<text x="10" y="7">Population {p.metadata["name"]} (id={p.id})</text></g>' # Label
1103+ for p in ts_full.populations()
1104+ if p.id < 3
1105+ ])
1106+
1107+ ts.first().draw_svg(
1108+ size=(1200, 250),
1109+ node_labels={}, # Remove all node labels for a clearer viz
1110+ style="".join(styles), # Apply the stylesheet
1111+ preamble=legend,
1112+ )
1113+ ```
1114+
1115+ SVGs can be nested, so it is even possible to add an entire SVG in the ` preamble ` .
1116+
10671117#### A fancy formatted plot
10681118
10691119Here we have activated the Y axis, and changed the node style. In particular, we have
0 commit comments