58 throw std::invalid_argument(
59 "Tree is not bifurcating. Cannot draw heat tree with inner node rows." 63 std::vector<size_t> tmp;
64 auto visits = std::vector<size_t>( tree.
node_count(), 0 );
66 auto const node_index = it.node().index();
70 ++visits[ node_index ];
76 tmp.push_back( node_index );
84 }
else if(
is_leaf( it.node() ) || visits[ node_index ] == 2 ) {
85 tmp.push_back( node_index );
96 auto result = std::vector<size_t>( sorting.size() );
97 for(
size_t i = 0; i < sorting.size(); ++i ) {
98 assert( sorting[i] < result.size() );
99 result[ sorting[i] ] = i;
122 std::vector<size_t>
const& order
124 if( order.size() != mat.
rows() ) {
125 throw std::invalid_argument(
"Wrong order size for reordering matrix rows." );
129 for(
size_t r = 0; r < order.size(); ++r ) {
130 assert( order[r] < mat.
rows() );
131 result.
row(r) = mat.
row( order[r] ).to_vector();
175 layout.height( std::max( 100.0, 6.0 * static_cast<double>( params.
tree.
node_count() )));
176 layout.width( layout.height() / 2.0 );
177 layout.align_labels(
true );
178 layout.text_template().anchor = SvgText::Anchor::kEnd;
188 throw std::runtime_error(
189 "Matrix has wrong size for making a heat tree. Has to be either tree.node_count(), " 190 "tree.node_count() - 1, or leaf_edge_count( tree )." 196 spacer_stroke.dash_array = std::vector<double>({ 2.0, 0.5 });
197 spacer_stroke.dash_offset = 2.0;
198 layout.set_label_spacer_strokes( spacer_stroke, layout.inner_node_spreading() );
202 std::vector<SvgStroke> strokes;
204 auto stroke = params.
stroke;
205 stroke.
color = color;
206 stroke.line_cap = SvgStroke::LineCap::kRound;
207 strokes.push_back( std::move( stroke ));
209 layout.set_edge_strokes( strokes );
213 auto svg_doc = layout.to_svg_document();
214 svg_doc.margin.left = svg_doc.margin.top = svg_doc.margin.bottom = svg_doc.margin.right = 200;
217 double const svg_pal_height = svg_doc.bounding_box().width() / 10.0;
218 double const svg_pal_top = 1.2 * svg_doc.bounding_box().height();
219 if( ! tree_color_map.
empty() ) {
222 svg_pal_settings.direction = SvgColorBarSettings::Direction::kLeftToRight;
223 svg_pal_settings.width = layout.width();
224 svg_pal_settings.height = svg_pal_height;
226 auto svg_scale =
make_svg_color_bar( svg_pal_settings, tree_color_map, tree_color_norm );
232 svg_doc.margin.bottom = 0.2 * svg_doc.bounding_box().height() + 2 * svg_pal_settings.height + 200;
235 if( ! svg_scale.first.empty() ) {
236 svg_doc.defs.push_back( svg_scale.first );
238 svg_doc << std::move( svg_scale.second );
247 svg_mat_set.
pixel_height = layout.height() /
static_cast<double>( matrix.rows() - 1 );
250 matrix, svg_mat_set, std::vector<std::string>{}, params.
column_labels 253 svg_doc.bounding_box().width() + 20.0, - svg_mat_set.
pixel_width / 2.0
255 auto const svg_matrix_left = svg_doc.bounding_box().width() + 20.0;
256 auto const svg_matrix_width = svg_matrix.bounding_box().width();
257 svg_doc << std::move( svg_matrix );
258 svg_doc.margin.right += svg_matrix_width + 200;
261 if( ! matrix_color_map.
empty() ) {
264 svg_pal_settings.direction = SvgColorBarSettings::Direction::kLeftToRight;
265 svg_pal_settings.width = svg_matrix_width;
266 svg_pal_settings.height = svg_pal_height;
268 auto svg_scale =
make_svg_color_bar( svg_pal_settings, matrix_color_map, matrix_color_norm );
272 svg_matrix_left, svg_pal_top
274 svg_doc.margin.bottom = 0.2 * svg_doc.bounding_box().height() + 2 * svg_pal_settings.height + 200;
277 if( ! svg_scale.first.empty() ) {
278 svg_doc.defs.push_back( svg_scale.first );
280 svg_doc << std::move( svg_scale.second );
Provides some valuable algorithms that are not part of the C++ 11 STL.
Default Color normalization, using a sequential linear scaling in the range [ min, max ].
SvgGroup make_svg_matrix(Matrix< Color > const &mat, SvgMatrixSettings settings, std::vector< std::string > const &row_labels, std::vector< std::string > const &col_labels)
bool is_root(TreeLink const &link)
Return whether the link belongs to the root node of its Tree.
utils::SvgDocument heat_tree(HeatTreeParameters const ¶ms)
Store a list of colors and offer them as a map for values in range [ 0.0, 1.0 ].
bool is_bifurcating(Tree const &tree, bool loose)
Return whether the Tree is bifurcating.
Container namespace for all symbols of genesis in order to keep them separate when used as a library...
utils::Range< IteratorEulertour< true > > eulertour(ElementType const &element)
std::vector< size_t > sort_indices(RandomAccessIterator first, RandomAccessIterator last, Comparator comparator)
Get the indices to the sorted order of the given range.
static std::vector< size_t > heat_tree_row_order_(Tree const &tree, LayoutSpreading spreading)
std::vector< std::string > column_labels
size_t leaf_node_count(Tree const &tree)
Count the number of leaf Nodes of a Tree.
std::vector< utils::Color > color_per_branch
Class for representing phylogenetic trees.
utils::Matrix< T > heat_tree_reorder_rows_(utils::Matrix< T > const &mat, std::vector< size_t > const &order)
MatrixRow< self_type, value_type > row(size_t row)
utils::Matrix< utils::Color > matrix
Base class for color normalization.
LayoutSpreading
Spreading of the nodes of a tree for drawing.
size_t node_count() const
Return the number of TreeNodes of the Tree.
std::pair< SvgGradientLinear, SvgGroup > make_svg_color_bar(SvgColorBarSettings const &settings, ColorMap const &map, ColorNormalization const &norm, std::string const &id)
bool empty() const
Return whether the Palette is empty, that is, no colors were set.
bool is_leaf(TreeLink const &link)
Return true iff the node of the given link is a leaf node.