widdowquinn / pyani

@@ -161,7 +161,7 @@
Loading
161 161
162 162
163 163
# Generate Seaborn heatmap output
164 -
def heatmap(dfr, outfilename=None, title=None, params=None, args=None):
164 +
def heatmap(dfr, outfilename=None, title=None, format=None, params=None, args=None):
165 165
    """Return seaborn heatmap with cluster dendrograms.
166 166
167 167
    :param dfr:  pandas DataFrame with relevant data
@@ -198,7 +198,7 @@
Loading
198 198
    # Tree
199 199
    newicks = None
200 200
    if args.tree:
201 -
        newicks = tree(dfr, fig, outfilename, title, params, args)
201 +
        newicks = tree(dfr, fig, title, format, params, args)
202 202
203 203
    # Return clustermap
204 204
    return fig, newicks
@@ -328,22 +328,23 @@
Loading
328 328
        return newick
329 329
330 330
331 -
def tree(dfr, fig, matfname, mat_title, params, args):
331 +
def tree(dfr, fig, title, format, params, args):
332 332
    """Generate a newick file and dendrogram plot for the given dataframe.
333 333
334 334
    :param dfr:  a dataframe
335 335
    :param fig:  a figure produced by sns.clustermap
336 -
    :param matfname:  name of the matrix plot file
336 +
    :param title:  name of the matrix plot
337 +
    :param format:  image file format being used
337 338
    :param params:  matrix plot parameters; including labels
338 339
    :param args:  Namespace
339 340
340 341
    """
341 342
    logger = logging.getLogger(__name__)
342 -
    # The header row must start with '#Names' for ClusterTree()'s text_array parameter to be satisfied
343 -
    # Create a text stream with the dataframe contents in the necessary format for ClusterTree
344 -
    # dfr.index.name = "#Names"
345 -
    # matrix = dfr.to_csv(None, sep="\t", header=True)
346 343
344 +
    # Get matrix name and run_id from the plot title
345 +
    matname, run_id = title.split("_", 1)[-1].rsplit("_", 1)
346 +
347 +
    # Dictionary to allow abstraction over axes
347 348
    sides = {
348 349
        "col": {
349 350
            "axis": fig.dendrogram_col,
@@ -356,18 +357,14 @@
Loading
356 357
    }
357 358
358 359
    # Create a linkage dendrogram and newick string for both rows and columns
359 -
    # newicks = {}
360 +
    newicks = {}
360 361
361 362
    for axis in sides.keys():
362 363
        # Generate newick format
363 364
        tree = hierarchy.to_tree(sides[axis]["axis"].linkage, False)
364 365
        logger.debug(f"Names: {sides[axis]['names']}")
365 366
        newick = get_newick(tree, tree.dist, sides[axis]["names"], "")
366 -
        newick_file = Path(args.outdir) / str(
367 -
            mat_title.replace("matrix", f"{axis}_newick") + ".nw"
368 -
        )
369 -
370 -
        # newicks.update({axis: newick})
367 +
        newicks.update({f"[{axis}_newick_{matname}_{run_id}]": newick})
371 368
372 369
        # Generate dendrogram
373 370
        # if 'dendrogram' in args.tree:
@@ -376,14 +373,12 @@
Loading
376 373
        # figtree = ClusterTree(newick, text_array=matrix)
377 374
        figtree = PhyloTree(newick)
378 375
        figtree.set_species_naming_function(get_species_name)
379 -
        figtree_file = str(matfname).replace("matrix", f"{axis}_tree")
376 +
        figtree_file = Path(args.outdir) / f"{axis}_tree_{matname}_{run_id}.{format}"
380 377
        logger.debug(f"{figtree}")
381 -
        figtree.render(figtree_file, layout=tree_layout)
382 -
        # with open(newick_file, 'w') as ofh:
383 -
        figtree.write(outfile=newick_file)
378 +
        figtree.render(str(figtree_file), layout=tree_layout)
384 379
385 380
    # Return the newick strings so we can save them in the database (eventually)
386 -
    # return newicks
381 +
    return newicks
387 382
388 383
389 384
def tree_layout(node):

@@ -55,12 +55,15 @@
Loading
55 55
# Distribution dictionary of matrix graphics methods
56 56
GMETHODS = {"mpl": pyani_graphics.mpl.heatmap, "seaborn": pyani_graphics.sns.heatmap}
57 57
SMETHODS = {"mpl": pyani_graphics.mpl.scatter, "seaborn": pyani_graphics.sns.scatter}
58 +
# TMETHODS = {"seaborn": pyani_graphics.seaborn.}
58 59
# Distribution dictionary of distribution graphics methods
59 60
DISTMETHODS = {
60 61
    "mpl": pyani_graphics.mpl.distribution,
61 62
    "seaborn": pyani_graphics.sns.distribution,
62 63
}
63 64
65 +
NEWICKS = {}
66 +
64 67
65 68
def subcmd_plot(args: Namespace) -> int:
66 69
    """Produce graphical output for an analysis.
@@ -92,6 +95,10 @@
Loading
92 95
    for run_id in run_ids:
93 96
        write_run_heatmaps(run_id, session, outfmts, args)
94 97
98 +
        if NEWICKS:
99 +
            write_newicks(args, run_id)
100 +
        NEWICKS.clear()
101 +
95 102
    return 0
96 103
97 104
@@ -197,16 +204,22 @@
Loading
197 204
        logger.debug("\tWriting graphics to %s", outfname)
198 205
        params = pyani_graphics.Params(cmap, result_labels, result_classes)
199 206
        # Draw heatmap
200 -
        GMETHODS[args.method](
207 +
        _, newicks = GMETHODS[args.method](
201 208
            matdata.data,
202 209
            outfname,
203 210
            title=f"matrix_{matdata.name}_run{run_id}",
211 +
            format=fmt,
204 212
            params=params,
205 213
            args=args,
206 214
        )
207 215
216 +
    # If Newick strings were generated, add them to NEWICKS.
217 +
    if newicks:
218 +
        NEWICKS.update(newicks)
219 +
208 220
    # Be tidy with matplotlib caches
209 221
    plt.close("all")
222 +
    return
210 223
211 224
212 225
def write_scatter(
@@ -252,3 +265,11 @@
Loading
252 265
253 266
        # Be tidy with matplotlib caches
254 267
        plt.close("all")
268 +
269 +
270 +
def write_newicks(args: Namespace, run_id):
271 +
    # If Newick strings were generated, write them out.
272 +
    newick_file = Path(args.outdir) / f"newicks_run{run_id}.nw"
273 +
    with open(newick_file, "w") as nfh:
274 +
        for name, nw in NEWICKS.items():
275 +
            nfh.write(f"{name}\t{nw}\n")
Files Coverage
pyani 20.09%
Project Totals (52 files) 20.09%
2089
Build #2089 -
2088
Build #2088 -
2090
Build #2090 -
2091
Build #2091 -
2097
Build #2097 -
2098
Build #2098 -
2099
Build #2099 -
2096
Build #2096 -
1
#
2
# This codecov.yml is the default configuration for
3
# all repositories on Codecov. You may adjust the settings
4
# below in your own codecov.yml in your repository.
5
#
6
coverage:
7
  precision: 2
8
  round: down
9
  range: 70...100
10

11
  status:
12
    # Learn more at https://docs.codecov.io/docs/commit-status
13
    project: true
14
    patch: true
15
    changes: false
16

17
comment:
18
  layout: "header, diff"
19
  behavior: default  # update if exists else create new
Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files. The size and color of each slice is representing the number of statements and the coverage, respectively.
Grid
Each block represents a single file in the project. The size and color of each block is represented by the number of statements and the coverage, respectively.
Loading