cli
for messaging, for consistency with tidyverse.General goal is to reduce label overlaps in Cnet plots
Many options, including considering ggraph
ot tidygraph
, however
both require re-creating pie/jampie graph node shapes that display both
fill colors and border outline (without hiding adjacent borders).
These strategies would not respect edge bundling, so that would either
be lost or would require porting to ggplot ecosystem somehow. Sigh.
Then use ggrepel
for non-overlapping labels.
grid
tool for non-overlapping labels,
and not ggplot2
.A simpler option is to allow direct x/y coordinate label adjustment. Current approach requires angle and distance from node center. Difficult to move one label "up and left a tiny amount". If given ability to adjust a label, it could be possible to adjust all labels to reduce overlaps. Potential workflow:
Apply user-provided adjustments. Easiest approach. Default nudge matrix is c(0, 0) for all nodes. Edit for specific nodes, relative to plot layout coordinates.
Future: Automated adjustments.
strwidth()
and strheight()
to define bounding boxes.plotrix
approach performs radial search in local space.
It works best when labels are placed in smart order, e.g. center
in a cluster, then working out toward edges.
Define clusters? Define center of each cluster. Sort labels by
distance from cluster center.fixSetLabels()
Define better default replacements.
Consider using mem_enrichment_heatmap()
as the top_annotation
for mem_gene_path_heatmap()
, including for example the dotplot format.
Easiest prototype might be to use +
to display the
gene-path heatmap rotated with rotate_heatmap=TRUE
beside the
enrichment heatmap,then merge the color legends:
R
ComplexHeatmap::draw(mpf$enrichment_hm + mpf$gp_hm,
annotation_legend_list=attr(mpf$enrichment_hm, "annotation_legend_list"),
merge_legends=TRUE)
row_title
for the enrichment heatmap when called by
mem_plot_folio()
, currently it uses numbers instead of LETTERS
.mem_enrichment_heatmap()
when used with dot plot, so each cell is square with the circle centered.Consider returning updated igraph
from jam_igraph()
Currently returns invisible(NULL)
.
igraph
values
such as node size, label size, label distance, etc.jam_igraph(output)
with no
additional arguments and have it (mostly) render the identical figure.Add unit tests.
Cover all basic functionality.
Examples and vignettes should already cover the core workflow.
Consider adjustments to make_point_hull()
font size
distance from hull
Big picture: Consider using venndir::JamPolygon
instead of sf
polygons.
Would calculate offsets, rescale, transform, using JamPolygon
functions.
sf
is heavy.mem_gene_path_heatmap()
Changed default caption to use ComplexHeatmap::Legend()
format
so it can be included along with color legends.
gene rows, set columns
labels to the top, split in two rows.Return added attribute "caption_legendlist"
.
apply_cnet_direction()
Change default logic to use pie.border
always instead of
switching to frame.color
when all borders are identical.
I think this logic should belong in the plotting function
to decide how to render nodes, jam_igraph()
Also more convenient when reviewing the data, user should only
have to look at pie.border
and not combination of pie.border
and frame.color
.
mem_enrichment_heatmap()
Consider adding top_annotation
using the colorV
colors per
enrichment, for consistency with mem_gene_path_heatmap()
and Cnet plots.
DONE. Add add_pathway_direction()
DONE. Helper function to add directional z-score column to enrichResult
data, using the formula from QIAGEN IPA:
z <- (N_genes_up - N_genes_down) / sqrt(N_genes_up + N_genes_down)
Call add_pathway_direction()
from multiEnrichMap()
when appropriate.
geneHitList
or geneHitIM
are provided, and
"z-score"
is not already defined in each enrichResult
object.
(Bonus points for checking the direction colname attribute.)
Review clusterProfiler::compareClusterResult-class
object
definition. For example clusterProfiler::merge_result(list(enrichResults))
.
Consider some form of integration, if possible, for example conversion
to/from to call similar functions in clusterProfiler
.
S4 object Mem
to replace list
returned by multiEnrichMap()
IT IS COMING
multienrichjam()
to replace multiEnrichmap()
?slots:
matrix
objectsmatrix
objectsmatrix
objectlist
of enrichResult
objectscharacter
vector of colors per enrichmentcharacter
column assignment (consider omitting to enforce
standardized colnames)methods:
mem_plot_folio()
, supporting functions: mem_gene_path_heatmap()
,
mem_enrichment_heatmap()
, mem2cnet()
enrichList()
- accessor for mem@enrichList
mem2dfs()
- create series of data.frame
summarizing content,
intended for export to Excel xlsx.mem2xlsx()
- direct export to Excel xlsx, calling mem2dfs()
.behaviors
multiEnrichMap()
returns Mem
object instead of list
mem_plot_folio()
may store parameters in the Mem
objectmem_gene_path_heatmap()
, mem_enrichment_heatmap()
could also
store/retrieve parameters from the mem
input object.mem_plot_folio()
optionally stores plots into mem
to maintian consistent plot attributesConsider Cnet
object that inherits igraph
?
It behaves as an igraph
object except its class is helpful for
generic functions: plot.Cnet()
, layout.Cnet()
, relayout.Cnet()
Unclear if S3 object type is preferred since it could inherit
igraph
(S3 object) characteristics.
Consider subgraph.Cnet()
or subgraph.igraph()
functions
Main purpose is to subset the layout as well as nodes.
require()
checks, since they should already be in Dependencies.gsubs()
which causes a warning upon loading multienrichjam
.
It conflicts with jamba::gsubs()
. They have slightly different logic.mem_plot_folio()
Enrichment heatmap should define row_title
to match
pathway_column_title
, LETTERS
by default.
It currently shows numbers.
mem_plot_folio()
- option to support RMarkdown output
Provide optional wrapper for RMarkdown output, specifically to print headings/tabs for each plot produced.
fig.height
, fig.width
.hook_preplot
and hook_postplot
to allow the user to run a custom function before and after each plot
is drawn.
That feels too complicated, when the main driver is just to print
an RMarkdown header.importIPAenrichment()
DONE. Consider handling gene identifiers so that the default behavior refers to each enriched gene by the original input gene symbol, and not the IPA-generated gene symbol. Some considerations:
"HSPA1A/HSPA1B"
, one experiment may find "HSPA1A"
significant,
another may find "HSPA1B"
significant. According to IPA, these
results are equivalent, in which case the IPA symbol "HSPA1A/HSPA1B"
would allow them to use the same identifier."Analysis Ready Molecules"
is available,
and follows expected convention used by Ingenuity.When multiple genes are combined to "one entity"
by IPA, and only one input symbol is retained in the
"Analysis Ready Molecules"
.
The driving use case: "HSPA1A"
and "HSPA1B"
are combined to
one gene entry "HSPA1A/HSPA1B"
by IPA. They are considered one
gene for the purpose of enrichment. If one or both genes were significant,
they would appear as "HSPA1A/HSPA1B"
by IPA.
The "Analysis Ready Molecules"
will list one symbol "HSPA1B"
as exemplar, and no entry will appear for "HSPA1A"
.
In this case there are two options:
"HSPA1B"
.
IMPLEMENTED with revert_ipa_xref=TRUE
(new default)."HSPA1A"
and "HSPA1B"
. In this case, we need the user to supply the
actual gene hits, so we retain only the gene hit the user provided.
NOT IMPLEMENTED."HSPA1A/HSPA1B"
, however this symbol will
not match any input gene hit list, or other expression data matrix.
IMPLEMENTED with revert_ipa_xref=FALSE
.Consider retaining the header section with analysis details, at least for text input.
multiEnrichMap()
Sometimes the gene rows in geneIM
do not match gene rows in memIM
,
causing an error downstream. The problem appears to happen when the
gene hit list does not match all entries in memIM
, causing geneIM
to have fewer rows.
memIM
- not ideal because we do not
want to lose data.geneIM
- which requires inferring the
incidence matrix. For directional data, it would impose 1
regardless
of the intended directionality, since no other source is available.edge bundling
Between two communities currently calculates the "central path" between the group centroids. Consider calculating the "central path" between the points with edges between the two communities.
igraph
adjustment scripting language?
Combines:
nudge_igraph_nodes()
: Fuscobac::x:0.01:y:-0.02adjust_cnet_nodeset()
: nodeset:A::degrees:45:x0.1:y-0.05:percent_spacing:7apply_nodeset_spacing()
: nodeset:B::percent_spacing:7adjust_cnet_nodeset()
, apply_nodeset_spacing()
Debug issue where label.dist
and label.degrees
are defined for
subset of nodes, leaving other node attributes NA
- which causes an
error in jam_igraph()
. Occurs when only one nodeset is adjusted.
percent_spacing
fails in adjust_cnet_nodeset()
when supplying custom nodegroups from community detection, and are
not proper Cnet nodesets.mem_gene_path_heatmap()
- lower priority but could be useful
Consider interactive view (plotly? InteractiveComplexHeatmap?) to enable hover text with the enrichment P-value, gene count, z-score. Could be particularly useful with directional output.
Consider optionally labeling the significant dots?
mem_legend()
- lower priority, eventually necessary
Consider using ComplexHeatmap::Legend()
for consistency with other
legends, and to allow combining multiple legends together.
S4 object mem
(or MEM
?) - higher priority - sooner the better
streamlined data content:
matrix
objectsmatrix
objectsmatrix
objectlist
of enrichResult
objectscharacter
vector of colors per enrichmentcolnames: character
column assignment (consider omitting to enforce
standardized colnames)
omit: multiEnrichMap
- in favor of mem_plot_folio()
, memIM2cnet()
omit: multiCnetPlot
- in favor of mem_multienrichplot()
optional: store output from mem_plot_folio()
to keep a series
of plots coordinated, using the same options: pathway_column_split
,
gene_row_split
, enrich_im_weight
, gene_im_weight
,
column_method
, row_method
(rename column_method
to pathway_method
?)
enrichment_hm
: Heatmap
output from
mem_enrichment_heatmap()
?methods:
mem_plot_folio()
, supporting functions: mem_gene_path_heatmap()
,
mem_enrichment_heatmap()
, mem2cnet()
enrichList()
- accessor for mem@enrichList
mem2dfs()
- create series of data.frame
summarizing content,
intended for export to Excel xlsx.mem2xlsx()
- direct export to Excel xlsx, calling mem2dfs()
.behaviors
multiEnrichMap()
creates MEM
object instead of list
by defaultmem_gene_path_heatmap()
, mem_enrichment_heatmap()
could also
store/retrieve parameters from the mem
input object.mem_plot_folio()
optionally stores plots into mem
to maintian consistent plot attributesmem_plot_folio()
argument do_which
- consider accepting character
string terms,
e.g. "enrichment_hm"
, "gp_hm"
, "cnet_collapse_set"
Consider new argument clusters_mem
for these uses:
collapse_mem_clusters()
When provided mpf$clusters_mem
as list
it may result in singlet
genes not connected to any pathways - these should (by default) be removed.
jam_igraph()
- debug
Apparently sometimes with singlet gene nodes it produces an error:
"Error in FUN(X[[i]], ...) : !anyNA(x) is not TRUE"
traceback pointed to this line:
sf::st_polygon(list(polym)) at jamenrich-igraphshapes.R#1635
mem_gene_path_heatmap()
Consider option to place the caption elsewhere.
mem_plot_folio()
, mem_gene_path_heatmap()
Consider a workflow to merge pathway clusters, to allow flexibility in how pathway clusters are defined.
"A"
and "B"
might be nearly identical.mem_gene_path_heatmap()
consider adding column top_annotation
with pathway directionality,
equivalent to the left_annotation
used for gene directionality.
Add row and column annotation padding by default, to help distinguish the central heatmap from the left and top annotations.
multiEnrichMap()
when supplied with geneHitIM
or geneHitList
, calculate the
z-score
using the IPA formula:
z <- (N_genes_up - N_genes_down) / sqrt(N_genes_up + N_genes_down)
as described [https://doi.org/10.1093/bioinformatics/btt703],
and in their FAQ: IPA FAQ - Statistical Calculations
DONE. multiEnrichMap()
DONE. geneHitIM
and geneHitList
are not behaving as intended, nor
consistently. They should be interchangeable and equivalent.
When geneHitIM
is supplied, it populates geneIMdirection
but
not geneIM
.
When geneHitList
is supplied, it populates geneIM
but not
geneIMdirection
.
When either are supplied, they should populate the relevant row
in geneIM
and geneIMdirection
.
Currently it is cumbersome to edit pathway labels.
It could be done for the mem
object itself, however the adjustment
might need to be different for different plot outputs: heatmap may not
work well using word-wrap, while Cnet plots might work best with word-wrap.
Publication figures might need an abbreviated label to save plot space.
mem_plot_folio()
Consider argument to enable custom adjustment of pathway labels.
mem_gene_path_heatmap()
DONE. Consider argument gene_annotations
to enable "geneIM"
,
"geneIMdirection"
.
mem$geneIMdirection
is present, include directionality
in the gene clustering step.mem$pathwayIMdirection
) similar to display of mem$geneIMdirection
.
New argument pathway_annotations
.Remove dependency on sf
in adjust_polygon_border()
use polyclip
package as it is much more lightweight, without requiring
RGEOS, LWGEOM, other world globe map-coordinate based libraries
which are not easily compiled on all computer systems using R.
Consider porting deconcat_df2()
to jamba
for wider re-use by jam
packages that would not otherwise need dependency on multienrichjam
.
Consider vectorizing edge arrow size
Currently all edge arrows must be the same size (the same limitation
is present with igraph::plot()
).
This is a niche feature, arrows are rarely used in multienrichjam
,
and use of differently-sized arrows does not have a driving use case.
(This feature is unlikely to move forward until needed.)
Consider ggraph
compatibility in future.
Many R packages use ggraph
for igraph
plotting, so it might make
sense for consistency to offer this feature. The output ggplot
objects
can be combined into larger figures using patchwork
or cowplot
easier than using base R plot()
functions.
ggraph
is mainly because the
returned ggplot
object is not a useful network graph, it is only the
instructions for visualization. As such, the layout, node customization,
is not persistent outside the ggplot
object. The package
clusterProfiler
migrated to ggraph
and now all the returned objects
are not useful because they cannot (easily) be customized and analyzed.ggraph
does not offer pie
nor coloredrectangle
node shapes.pie
nodes can be emulated with geom_pie()
but
(1) is painfully slow to render because it is not vectorized,
(2) does not use inner borders, which allow adjacent wedge borders to
be shown beside each other without overlapping.geom
for jampie
node shape that accepts
pie wedge border colors drawn as inner border, with optional outer border
color that also does not overlap the optional inner border.ggraph
compatible
methods. It involves calculating edge bundles, then rendering the
curved edges, optionally with arrow heads.jam_ggraph()
may be the ggraph
equivalent of jam_igraph()
for plotting igraph
objects.Integrate directionality with more steps in the workflow:
mem_gene_path_heatmap()
Create bookdown
documentation
Should it use a separate Github repository? (Probably yes.)
It looks like "jokergoo/circlize_book"
is the repo for the bookdown site.
Refactor multiEnrichMap()
- maybe new function multienrichjam()
?
create mem
S4 object with slots, print, summary functions
suggested methods:
plot()
could default to mem_gene_path_heatmap()
to show all dataprint()
could print summary of content:
enrichments, pathways, genesas.data.frame()
- convert to wide data.frame
summary?memIM()
, geneIM()
, enrichIM()
convenient access to slot datalist
format for IMs?slots:
memIM
: gene/pathway matrixgeneIM
: gene/enrichment matrixenrichIM
: pathway/enrichmentgeneIMdirection
: optional direction per gene/enrichmentgeneIMcolors
: colors assigned per gene/enrichmentenrichIMdirection
: optional direction (z-score) per pathway/enrichmentenrichIMcolors
: colors assigned per pathway/enrichmentenrichIMgeneCount
: integer number of genes per pathway/enrichmentremove steps that create embedded Cnet and Emap igraph
objects:
multiCnetPlot
, multiCnetPlot1
, multiCnetPlot1b
, multiCnetPlot2
multiEnrichMap
, multiEnrichMap2
multiEnrichDF
- consider saving data.frame
with clear namemultiEnrichResult
- What content is stored here?New object classes:
"mem"
: store output from multiEnrichMap()
list
format used currently.)params:
cutoffRowMinP
)"mem_plots"
: store mem_plot_folio()
data for re-use.
New wrapper function multienrich()
to replace multiEnrichMap()
?
streamlined refactor and replacement for multiEnrichMap()
mem_plot_folio()
memIM
data as SummarizedExperiment
for convenient
use with ComplexHeatmap::Heatmap()
via jamses::heatmap_se()
.returns mem
object.
Update mem_plot_folio()
input mem
object
mem2emap()
plot output.consider using jamses::heatmap_se()
for heatmap functions
jamses
as dependency, along with its dependenciesjamses::heatmap_se()
be moved to new package focused
only on SummarizedExperiment heatmaps?sechm
which is much less capable, but
has the same inspiration.
It provides row scaling (ack) as a recommended (!) option.
(Problematic, sorry to say. For gene expression
data, the magnitude of change is important, and matters.
To rescale the numeric range for consistency is counter to the
biology, and to the technology. The technology has measurement
limitations, for which seeing the actual numeric differences is
important for assessing whether changes are reliable from that platform.
These differences also transfer into follow-up confirmation assays,
where changes below a threshold are not feasible to confirm.
In general, gene (transcript or protein) expression fold changes are
relatively consistently measured for each gene, so to enhance
the apparent fold change of one gene to fit the fold change of another
gene is not necessary, certainly not by default.)Consider new R package for SummarizedExperiment heatmaps
move jamses::heatmap_se()
into this package
platjam::design2colors()
into this packageminimize R package dependencies
R packages to review
Bioconductor package "ConsensusClusterPlus"
which can be
used to determine appropriate k
values for k-means clustering,
with metrics to assess consistency of cluster assignment.
"GeneTonic"
function ggs_graph()
produces a Cnet plot
which they export to visIgraph()
for interactivity;
enrichment_map()
creates EnrichMap."monaLisa"
- motif enrichment, extends HOMER theme; nice heatmap
Motif labels"profileplyr"
- coverage heatmap using tidyverse plyr syntaxDONE: reorder_igraph_nodes()
When orderByAspect=TRUE
, and it detects tall-skinny aspect ratio,
it appears to be applying the y-axis sorting bottom-to-top instead of
top-to-bottom.
The culprit was spread_igraph_labels()
default argument,
changed from nodeSortBy=c("x", "y")
to nodeSortBy=c("x", "-y")
.
mem_gene_path_heatmap()
Slightly increase the spacing between heatmap body and row/column annotations. Currently the gap between heatmap row/column split is identical to the gap between heatmap and row/column annotations, which makes it harder to distinguish one from the other.
ComplexHeatmap::ht_opts()
but the option is hard to remember, and would ideally need to be
set back to the previous value after drawing the plot.mem_plot_folio()
DONE: The enrichment dot plot (or enrichment heatmap) should be created
after the gene-path heatmap is created, in order to define
pathway clusters using gene content, rather than defining pathway
clusters using the -log10(Pvalue)
matrix.
consider new function to convert IPA enrichment data to geneHitList
list element "Analysis Ready Molecules"
is provided in the IPA output,
and this data can be used to re-create the directional hit matrix used
during import (if directionality such as fold change was provided to IPA).
consider new function to evaluate gene-pathway heatmap output
The driving use case is selecting pathway_column_split=5
upfront,
but realizing perhaps 3 clusters would be preferred based upon the
content.
sometimes two clusters can and perhaps should be merged together
consider new function to edit vertex attributes?
use case: existing igraph
object nodes have attributes to modify:
nodeType="Set"
to edit labelspie.color
, pie.border
) in list
formigraph
object with attribute modified and stored
in the same state as present originally (e.g. atomic remains atomic;
list remains list).Which format seems most reasonable?
gsub_vertex(g,
pattern_l=list(
nodeType=c(Set="^(WP|KEGG|BIOCARTA|GO|REACTOME)_")),
replacement_l=list(
nodeType=c(Set="")))
gsub_vertex(g,
subset_attr="nodeType",
subset_attr_value="Set",
pattern="^(WP|KEGG|BIOCARTA|GO|REACTOME)_",
replacement="")
gsub_vertex(g,
subset_attr_l=list(nodeType=c("Set")),
pattern="^(WP|KEGG|BIOCARTA|GO|REACTOME)_",
replacement="")
consider new function to adjust igraph
node colors in all forms
modify all fill color attributes color
, pie.color
, coloredrect.color
frame.color
, pie.border
,
coloredrect.border
frame.width
, pie.lwd
, coloredrect.lwd
relative to each other.
For example when pie.lwd
and pie.border
are both defined
(and not transparent), frame.width=0.1
, otherwise frame.width=2
.mem_plot_folio()
Debug edge cases where pathway_column_split=4
does not match
the output number of column split following hierarchical clustering.
Debug edge case where there are not enough pathways or genes to support the gene-pathway heatmap workflow. E.g. only 1 or 2 pathways, or only 1 or 2 genes.
multiEnrichMap()
Debug error "multiEnrichMap(): geneHitIM does not contain 5 rows present in geneIM, default values will use 1."
rownames(mem$geneIM)
are not found in
rownames(geneHitIM)
.geneIMdirection
so it does not store "+1"
and instead shows zero or NA. Genes should be shown but without
associated direction.reorder_igraph_nodes()
Currently orderByAspect=TRUE
will order nodes based upon the
aspect ratio of each nodeset.
Ideal world: when nodes are sorted by something like color, calculate the aspect ratio of nodes within that color. Situation: Assume a tall-skinny nodeset, sorted top-to-bottom by different colors. One color has 12 entries, the nodeset is 12 nodes wide, so this color appears horizontal among the other nodes. When sorting by border color, it goes top-to-bottom, which is not visually intuitive.
apply_cnet_direction()
DONE: changed default col
to use colors:
c("blue", "grey80", "firebrick3")
with breaks c(-1, 0, 1)
.
change all frame.lwd
to frame.width
before frame.lwd
is widely used.
consider backward compatibility: when frame.lwd
is defined in an
igraph
object, copy its values into frame.width
, then proceed
using frame.width
for all other operations.
mem_legend()
DONE: new argument pt.lwd=2
to control the line width used only for point
borders, useful when do_direction=TRUE
. The argument pt.lwd
already
gets passed to legend()
however making it a formal argument here
helps make the option more clear for users.
Auto-detect whether to enable do_direction=TRUE
, by checking if
any frame.color
or pie.border
are defined with red/blue colors.
Bonus points for using the same colors defined in frame.color
or
pie.border
, however that may be risky if those colors vary based
upon some fold change value, or vary based upon contrasting with
the node or pie fill color.
jam_igraph()
Consider handling V(g)$shape="circle"
as shape "jampie"
during
rendering. Certain older Cnet plot igraph
objects appear to break
the default shape="circle"
rendering, some cryptic error about
names()
not being defined when expected. The error does not appear
with igraph::plot.igraph()
, so it is specific to jam_igraph()
.
shape="jampie"
rendering method already implemented, which
would keep all borders consistent when displaying a mixture of
shape="circle"
and shape="jampie"
nodes.pie.color
defined
it will be used when shape="jampie"
even if the user specified
shape="circle"
(which should only use color
).
In that case, when a shape="circle"
node is being rendered internally
as shape="jampie"
it should first copy color
into pie.color
for
those nodes; frame.color
to pie.border
; and
frame.lwd
(frame.width
) to pie.lwd
.DONE: Fix bug with node rendering, caused by recent version of igraph
adding vertex.frame.width
(and not vertex.frame.lwd
ugh).
NULL
or missing vertex.frame.width
causes an error.
Ultimately caused by no default value defined in the custom function
default_igraph_values()
, which was necessary to create since
igraph
does not export that function.
vertex.frame.width
to default values.Longer term fix is to replace all references to vertex.frame.lwd
with vertex.frame.width
, before the precedent is set.
Fix errors caused by "stringsAsFactors=TRUE"
DONE: rank_mem_clusters()
Fix errors caused when there is only one (or zero) genes.
mem_gene_path_heatmap()
and mem_plot_folio()
mem_enrichment_heatmap()
color legend changes:
Show actual P-value c(1, 0.05, 0.01, 0.001, 10^-4, etc.)
using
expression
for labels, and continue using -log10(p)
for color
assignment.
heatmap_legend_param=list(break_dist=1)
which
causes the numeric labels to be evenly spaced, instead of having the
labels at uneven intervals, often with angled lines connecting to
the color legend.c(1, 0.051, 0.05, 0.01)
in order to show that 0.051
is not colorized, but 0.05
is colorized.
The smooth gradient is actually more effective at conveying that effect
without additional labels.Nodes with shape="jampie"
and frame.lwd=0
are still rendering the
frame color outside the inner borders. When frame.lwd=0
there should
be no frame drawn even when frame.color
is defined with a color.
Big picture musing: Consider replacing base R plotting functions
with corresponding grid
functions.
The vwline
R package (P. Murrell) is capable of drawing
internal/external lines.
gridGraphics
package also provides better methods of
clipping curved lines to the edge of a node border for example.igraph
node shape functions into corresponding grid
format. It is effectively
similar to repeating much of ggraph
, except that this approach
can be customized. The ggraph
approach in ggplot2
is more or
less untouchable in terms of providing customization. Ugh.ggraph
, then use vwline
/gridGraphics
for rendering. Also
need to write custom edge bundling function, since those in ggraph
are wholly insufficient. Yeah, this is a no for now.reorder_igraph_nodes()
, reorderIgraphNodes()
DONE: method to specify specific nodes or nodesets to be reordered
motivation is to allow sorting based upon relative aspect ratio of nodes, so a nodeset whose nodes are "tall-skinny" can be sorted top-to-bottom, and nodeset whose nodes are "short-wide" can be sorted left-to-right. Frankly, not sure if the inconsistency works for all network layouts, but for sure the top-to-bottom is not ideal for "tall-skinny" nodesets, it is not visually intuitive.
consider new igraph shapes, intended to enable inner/outer border, frame.lwd
Do these make sense?
shape.jamcircle.plot()
- enable custom frame.lwd
for shape="circle"label_communities()
generalize this method to determine keywords most represented in any set of pathway names.
Low priority visual enhancement, color Cnet edges by Set.
Consider coloring Cnet edges by categorical color, by Set It may help clarify node groupings, while also reinforcing which edges connect to particular nodesets. Unclear whether added color would be confusing or beneficial.
Low priority: It may be useful to create vectorized functions:
polygon()
NA
coordinates.text()
: enable multiple family, srt
lines()
: enable multiple col, lty, lwd for split lines, similar
to segments()
except enabled for multiple lines split by NA
coordinates.jam_igraph()
Return the input igraph
object with all relevant object attributes
updated to reflect the plot parameters.
The returned object could be plotted directly without any customization.
Consider storing/using edge coordinates inside the igraph
object.
However, whenever layout is re-calculated, edge coordinates would likely
become invalid. It would be tricky to handle.
edge bundling and edge clipping integration
DONE: Most scenarios described below.
This situation is not a visualization problem when:
The situation is only a visible problem when:
Proper edge clipping would probably be done by calculating the edge from the node actual center point, then clipping edge where it exits the node shape border.
Implementation may benefit from storing the edge coordinates as an edge attribute, to be used by the clipping function when present. Absence of custom edge coordinates would cause the clipping function to use linear edge coordinates.
jam_igraph()
, proposed drop-in replacement for igraph:::plot.igraph()
:
FIXED: This function does not seem to handle edge arrows, nor does it shorten edges based upon node sizes.
When layout is not defined, the xlim/ylim values sometimes do not match the dynamic layout calculated on the fly.
igraph shape "ellipse"
DONE: it should have a proper "clip" function, in order for edge arrows to appear at the border of each node
igraph "coloredrectangle" shape
DONE: The coloredrect.border should also be capable of adjacent lines that do not overlap.
reorder_igraph_nodes()
DONE: to be fancy, it should also propagate changes to label.dist
and label.degree
, as created by spread_igraph_labels()
,
since switching coordinates for two nodes should also switch
the label.degree
and label.dist
associated with those
coordinates.
jam_igraph()
It shows some lag before plotting all nodes vectorized, check
if the edge bundling is the slow step, and optimize as needed.
UPDATE: Yes the edge bundling step is introducing lag; or the
resulting curved lines are being plotted slowly?
Another good reason to store edge bundle coordinates in the igraph
.
mem_legend()
consider using ComplexHeatmap::Legend()
for consistency with
future Cnet-Heatmap usage, and because that mechanism is really nice.
Refactor multiEnrichMap()
likely create new function multienrich()
so multiEnrichMap()
can
be deprecated and remain for backward compatibility.
mem_plot_folio()
with defaults, and
store results back into the multienrichResult
.Consider multienrichResult
object type?
list
object, with proper slot names.print()
/summary()
function to display summary info
about number of genes, pathways, etc.Consider multienrichPlot
object type?
No, the decision is to re-use multienrichResult
.
multienrichResult
with alternative clustering if necessary.mem_plot_folio()
to produce gene-pathway heatmap, they have
to use the same arguments in subsequent steps otherwise the
clusters will differ, and it is not clearly indicated to be
a problem.mem_plot_folio()
may likely return the multienrichResult
after updating internally stored data. It should have option to
use existing results.
Write a more directed vignette showing at least two common use cases:
Enrichment using clusterProfiler::enricher()
, then multi-enrichment.
"Export All"
from within the Ingenuity IPA app.Enrichment using some other external (non-R) tool, for example DAVID.
Write a vignette focused solely on Cnet plot custom layout options. Background:
Very common workflow results in Cnet plot to summarize the findings.
nudge_igraph_node()
. Note this function
can be called on a list
of nodes using nodes_xy
, or using vectors
with nodes
, x
, y
.Adjust sets of nodes:
adjust_cnet_nodeset()
- Usually for sub-clusters of gene nodes,
move the whole group, adjust intra-group node spacing,
or rotate the group around the group center.apply_nodeset_spacing()
- Apply a minimum spacing between
nodes, for each nodeset.adjust_cnet_set_relayout_gene()
- Adjust "Set" nodes manually,
then fix them in place but allow "Gene" nodes to move during re-layout,
usually with relayout_with_qfr()
Adjust all nodes:
layout_with_qfr()
, layout_with_qfrf()
, relayout_with_qfr()
-
All are wrappers to qgraph::qgraph.layout.fruchtermanreingold()
with convenient defaults. layout_with_qfr()
returns coordinates;
layout_with_qfrf()
returns a layout function with user-defined
repulse
argument; relayout_with_qfr()
updates layout in-place
for an igraph
object, storing in graph_attr(g, "layout")
.rotate_igraph_layout()
- rotate the layout coordinates by some
user-defined degree angle.spread_igraph_labels()
- positions node labels radially around
nodes, based upon the average incoming edge angle.reorder_igraph_nodes()
- within each nodeset, reposition nodes
in order of node color, border color, then label.
A nodeset is defined as a set of nodes that all share the same
connections, which is mostly only useful for bipartite graphs
such as Cnet plots. This function performs the node re-ordering
for all nodesets, across the whole igraph
object.plot with jam_igraph()
igraph::plot()
uses a for()
to iterate each node.pie
rendering, also vectorized.mark.groups
add dev functions layout_cnet()
and related iterative layout functions.
mechanism to store edge coordinates in igraph
object
to my knowledge, this functionality does not exist in igraph
,
nor is it represented in ggraph
or tidygraph
objects.
However tidygraph
may have capability to supply specific edge
coordinates if they exist, so it might be the closest to
implementing this feature.
igraph::plot()
is not equipped to use edge coordinatesggraph
is not equipped to use edge coordinates, it only creates
edge coordinates based upon the edge geom_
being used.The driving use case is to define edge coordinates to handle:
Reasons to want edge coordinates upfront:
Issues raised when storing edge coordinates:
rotate_igraph_layout()
could rotate nodes and all edges together.nudge_igraph_node()
and adjust_cnet_nodeset()
must decide
whether to adjust edges by simple scaling, or simply invalidate
all edges, then force the user to re-calculate edge coordinates.useful helper functions
validate_edge_coords()
- Test whether edge coordinates match
node coordinates. If not, then delete or replace edges with linear
equivalent.adjust_edge()
- Wrapper function to adjust the curvature,
placement, rotation, of edges. Could be called when rotating node
layout, to rotate edges accordingly.bundle_edges()
- Wrapper to apply bundling to one set of edges
together as a group. Optionally define specific coordinate(s)
through which the bundling loess curve is routed.get_cnet_nodeset()
This function is called several times by internal functions, and could therefore be much faster than currently.
Refactor by using igraph::as_adjacency_matrix()
.
Subset rows for nodeType="Gene"
and columns for nodeType="Set"
.
Then should be able to convert rapidly by venndir::im2list()
or some pasteByRow()
magic, produce nodeset per node (row).
Finally, split node names by nodeset.
node adjustment to prevent label overlaps
Idea: "stretch" out nodeset nodes "to the right", which fixes the left edge of the nodeset, then expands the node spacing outward as fraction of current range of nodeset nodes. For example, expand to the right by 10%, to improve side-to-side spacing, since label overlaps typically occur with nodes at the same y-level.
Future idea to reduce node label overlap is to treat it like biscuit dough under a rolling pin. Stretch subset of nodes in each direction until the labels no longer overlap. The trick is to stretch nodes away from other nodesets, so it does not cause new overlaps with other nodes.
adjust_cnet_nodeset()
Consider option to restrict "expand" to x- or y-axis expansion. Basic idea is to limit expansion to "widen" the node spacing, or to make node spacing "taller". The "widen" option is helpful to reduce label overlaps for nodes directly beside each other.
spread_igraph_labels()
ideal case: somehow take into account the edge bundling to calculate input angle to each node, rather than straight vector from node to node.
node_groups
- spread labels relative to node group centroid, so labels
in this cluster of nodes will be spaced out from each other.
Bonus points for taking into account the overall average input angle to
nodes in each group, and applying a fraction of that offset along with the
node-to-group offset. For example, for a node group in the top right,
they generally point to the top-right, but are fanned out slightly so the
bottom-left-most node is not fanned out to bottom-left, but maybe center,
or only slightly bottom-left of the node.
new layout functions specific for Cnet plots
iterate_qfr_layout()
- R code version of
qgraph::qgraph.layout.fruchtermanreingold()
with custom addition of
node "shells", and option to call iterate_node_group_distance()
iterate_node_group_distance()
- R layout intended only to enforce
separation across node groups (defined by get_cnet_nodeset()
) so there
is additional space between nodesets in the layout.layout_cnet()
- wrapper function that calls rounds of layouts.
This series of steps is currently the best default layout to generate
the most readable Cnet plot possible.
Other ideas:
bubble_force()
calculation for minimum distance,
instead of the linear desired distance force.Code it in Rust, use R package expandr
to integrate the Rust function
into the package via an R function. Follow C++ code steps used by
qgraph:::qgraph_layout_Cpp()
. It doesn't seem that these layout
iterations are particularly good for multi-threading, however.
mem_gene_path_heatmap()
add option to display gene incidence matrix (left annotation)
using geneIMdirection
colors, to represent up/down.
add plot_cnet_heatmaps()
make default arguments as minimal and close to default settings as possible
adjust_cnet_nodeset()
COMPLETE: add minimum percent spacing, similar to apply_nodeset_spacing()
except
to operate on only one nodeset at a time.
shape.jampie.plot()
which calls jam_mypie()
:
When drawing borders for multiple pie shapes, the overlapping border are overdrawn, hiding all but the last border drawn.
polygon()
functions.Workaround involves sf::st_buffer()
to calculate a buffer inside
each polygon, creating a "donut" filled with the border color. In
principle, this issue tends to occur in relatively few nodes for typical
Cnet plots, however it could be substantial performance hit.
sf::st_polygon
objectsf::st_buffer()
.multiEnrichMap()
accept p_cutoff
and deprecate cutoffRowMinP
for future removal.
p_cutoff
is used in other package functions, as is min_count
.
mem_enrichment_heatmap()
problem: style="dotplot"
and style="heatmap"
have very different
visual effects, the dotplot de-emphasizes significance in favor of
gene count (point size) - smaller gene count hides significance.
The pale bivalent colors are very close to white, while "Reds"
color
gradient is much more distinctive.
point_size_min=3
and point_size_max=10
may help?style="hybrid"
and implement both.S4 objects?
mem
:
multiEnrichMap()
print()
but also for clarity during the workflow. The mem
object can be
clear input to other functions.cnet
:
igraph
and extends assumptions, again mainly for clarity
as input argument to other functionsmem_gene_path_heatmap()
option to display dot plot format at the top of heatmaps, equivalent
to calling mem_enrichment_heatmap()
. Benefit would be to indicate
direction (color) and number of genes (size) in addition to
P-value (intensity).
fix reorderIgraphNodes()
DONE: add "frame.color":
sortAttributes=c("pie.color", "pie.color.length", "coloredrect.color", "color", "pie.border", "frame.color", "label", "name")
future: make sort more intelligent, so it uses appropriate color based upon node shape during the sort.
shape="pie"
: use "pie.color", "pie.border", "frame.color", "label", "name"shape="coloredrect"
: use "coloredrect.color", "coloredrect.border", "frame.color", "label", "name"shape="circle"
or similar:
use "color", "frame.color" and ignore "pie.color", "pie.border",
"coloredrect.color", "coloredrect.border", "label", "name"DONE: Include gene direction in the workflow:
DONE: Add geneIMdirection
to mem object.
geneHitIM
input to multiEnrichMap()
.geneIMdirection
to mem
object, and/or cnet
igraph
object.memIM2cnet()
should optionally use enrichIMdirection
to apply
border color.DONE: mem2cnet()
as its own function, minor variation and extension to
memIM2cnet()
which only uses the memIM
portion of the data.
jam_igraph()
should recognize lwd
when plotting nodes. This change
diverges from default behavior in igraph
which only uses par("lwd")
as a global adjustment for all lines while plotting nodes, therefore
does not allow any nodes to have different line widths.Gene-Path heatmap rows should optionally indicate direction, possibly another stripe using geneIMdirection.
multiEnrichMap()
should call mem2cnet()
- or just avoid this step altogether since
the cnet
process is better done with mem_plot_folio()
enrichMap
and cnet
steps altogether.mem_plot_folio()
FIXED: mem_enrichment_heatmap()
does not honor do_plot=FALSE
.
mem_enrichment_heatmap()
DONE: add argument cluster_rows
to allow cluster_rows=FALSE
.
Now that jam_igraph()
and node shapes "jampie"
render the
pie.border
and frame.color
, which can indicate the direction
of change for each gene, in context of each enrichment test, some
other changes should be made to the workflow:
Consider adding pie.lwd
to recognized attributes in
shape.jampie.plot()
, but confirm that this argument can be used
when rendering "jampie"
node shapes. Currently the line width
can only be adjusted with par("lwd")
which is a global setting.
frame.color
(vertex.frame.color
) should probably
be set to NA
or "transparent"
so the frame color is not visible
for pie nodes. It shows up as a small white line now, which was not
visible previously.reorderIgraphNodes()
should include pie.border
and frame.color
in sensible default locations, so nodes will also be sorted by these
values when relevant, without the user having to add these columns.New function to populate frame.color
and pie.border
for Cnet plots.
pie
has only one value, apply color to frame.color
pie
has multiple values, and different directions, apply
colors to pie.border
pie
has multiple values, and all have the same direction, apply
colors to frame.color
frame.color
to default,
and set all pie.border
to "transparent"
or NA
.Need to include gene direction of change in the workflow:
Some easy method to include direction of change in the multiEnrichMap()
workflow, for example argument geneHitList
currently uses a character
vector, but could accept integer
vector direction with genes stored as
character
labels, same as used with venndir
signed input lists.
frame.color
and/or
pie.border
colors are defined.mem_gene_path_heatmap()
option to represent direction of change
in the gene_im
incidence matrix.Edge bundling makes assumptions for bipartite graphs (cnet) that are difficult to use with normal graphs.
edge_bundle_nodegroups()
probably needs to subset edges
involved in each nodegroup before bundling all edges connected
to these nodes. Currently, nodes are assumed to share all
connections, but the effect should occur for edges where both
ends of the edge are contained in the nodegroup entries.
nodegroup
"."edgegroup"
, which would probably be the
optimal approach for edge bundling, apart from implementing another
technique similar to force-directed, hierarchically-defined, or
density-directed edge bundling.consider an option to specify the "midpoint" for a nodegroup, to allow some control on the spline curvature. Bonus points for allowing multiple points in order, to influence a path.
jam_igraph()
fancy effect: allow edge colors to have multiple values, then
interpolate color along each edge. For bundled edges, make
a gradient equal to the number of line segments. For straight
edges, break into detail
number of pieces. The detail
argument
is also used by the edge_bundle_*()
functions.
subset igraph
object by nodes, with added benefit that the
graph_attr(g, "layout")
will also be subset, if present. It is
odd that the default igraph::subgraph()
function would subset
the graph, leaving the layout which inevitably causes an error.
mem_gene_pathway_heatmap()
would be useful to have an option to subset enrichments,
this option would likely be useful to mem_plot_folio()
, and
mem_enrichment_heatmap()
, so the effect could cascade to
subsequent functions.
new function idea? subset_mem()
Could be useful to accomplish the item above, to subset by enrichments
prior to mem_plot_folio()
related functions.
enrichIM
does not also
update corresponding memIM
data. Data to be updated:geneIM
, geneIMcolors
, geneIMdirection
- simple subset by colnamesenrichIM
, enrichIMcolors
, enrichIMgeneCount
- simple subset by colnamesmemIM
- re-create after updating geneIM
enrichList
- simple subset by nameOthers not necessary for mem_plot_folio()
:
multiEnrichMap
, multiCnetPlot
should be re-created using
methods in multiEnrichMap()
. To be fair, these objects are not
that useful anymore, since mem_plot_folio()
is generally preferred.mem_gene_pathway_heatmap()
when supplied with custom column_split
throws an error when cluster_columns=TRUE
.
internally it uses amap::hcluster()
to generate a dendrogram/hclust
ComplexHeatmap::Heatmap()
pathway_column_weight
.A proper solution would be to provide a custom function for cluster_columns
that internally combined the incidence matrix and enrichment matrix data
together prior to clustering. If this function receives a
numeric matrix with proper colnames, it should work.
COMPLETE: mem_plot_folio()
argument gene_row_title=NULL
is being passed
to mem_gene_pathway_heatmap()
and is therefore not using the default
row_title=letters
.
mem_plot_folio()
mem_plot_folio(mem, node_factor=5, label_factor=1.5)
mem_plot_folio()
is passing ...
to ComplexHeatmap::Heatmap()
which
does not accept ...
and throws an error when receiving extra arguments....
to arguments accepted by Heatmap()
. I feel like
there is an R package function to handle this scenario, so I can avoid
writing do.call(Heatmap, custom_args)
.Workflow that starts with pathway-gene incidence matrix upfront,
bypassing the multiEnrichMap()
workflow altogether.
memIM2cnet()
to convert pathway-to-gene incidence matrix to Cnet igraph
.
Requires geneIM
which is the enrichment-to-gene incidence matrix.
In the driving example, each enrichment would represent a disease subgroup,
with the full set of differential genes associated to each subgroup.
enrichIM
which contains enrichment-to-pathway whose values
are P-values. When this data is not supplied, it should use 0.001 by default.
I think these values are only used as an optional gradient color for the
pathway nodes.geneIMcolors
which is the same as geneIM
except the cells
contain colors to use for each gene. Currently the function does not
fill these colors, the best method is to use colorjam::matrix2heatColors()
R
geneIMcolors <- colorjam::matrix2heatColors(x=geneIM,
colorV=colorV)
option to assign pathways to "functional themes" based upon presentation by Adeline Chin in Dr. Hanna Kim' group.
This step may "collapse" multiple pathways together, similar to grouping functional groups: union of genes, lowest enrichment P-value.
heatmap_row_order()
, heatmap_column_order()
should return a flat
vector when there are no row_split or column_split, respectively.
Currently data is returned as a list of one-length vectors.
Consider moving into jamba
package, in case this function
needs to be re-used, it should not require loading the full
multienrichjam
package, which itself requires things like
igraph
, clusterProfiler
, qgraph
, DOSE
, matrixStats
.
jamba::heatmap_row_order()
and jamba::heatmap_column_order()
to ensure any functions or packages calling this function will
succeed without error.This document describes plans for enhancements to the multienrichjam R package.
Now that directional z-score can also be associated with enrichment
P-values, heatmaps might need to use a bivariate color scale, to
indicate enrichment and directionality. See "stevens.bluered".
For example the mem_enrichment_heatmap()
colors nodes by enrichment
P-value, more intense is more significant enrichment.
The z-score direction is used to apply red "activated" or blue "inhibited".
However, pathways with no z-score, or z-score below the threshold
are colored red by default. They should use a neutral color.
For IPA "Upstream Regulators" it sometimes offers a direction
implied by the activation z-score
. Design idea is to implement
the directionality so it can be included in downstream analyses.
mem_enrichment_heatmap()
- currently shades by the -log10(pvalue)
however if there is directionality, it could be signed
+
for activated,
-
for inhibited. Then the heatmap color scale would use blue-white-red
color gradient.mem$enrichIMdirection
contains matrix of direction, by default 1
means all have same direction.During multiEnrichMap()
it filters for topEnrichN
entries for
each enrichment. It might be useful to retain the rank number for
each enrichment, to review when setting a different topEnrichN
threshold.
mem$enrichIMgeneCount
contains matrix of gene countsmem$enrichIMrank
contains matrix of pathway rank (after filtering gene count)COMPLETE: mem_enrichment_heatmap()
- the heatmap circles and legend circles
are not the same size - they should be fixed to the same absolute size.
COMPLETE: Optionally label each heatmap cell with the number of genes for visual reinforcement.
COMPLETE: When there are more than 3 enrichments, the color legend on the gene-pathway heatmap becomes unwieldy - taking over the whole figure.
Optionally (and by default) hide color legend for the gene-pathway heatmap.
COMPLETE: The gene-pathway heatmap use_raster=TRUE causes artifacts in output, it should be disabled by default. In future, debug why things go wrong.
I think the bug is caused by rasterization being done on underlying numbers
before the color ramp is applied, in which case this problem cannot be
solved when colorize_by_gene=TRUE
since categorical values are assigned
numbers which are not a proper color gradient.
Replace multiEnrichMap()
with multienrichjam()
and simplify the arguments:
p_cutoff
color_sub
Port mem_enrichment_heatmap()
argument colorize_by_gene=TRUE
to
use ComplexHeatmap::Heatmap()
instead of jamba::imageByColors()
for consistency, also so it can support style="dotplot"
.
jam_igraph()
with rescale=TRUE
should also scale igraph vertex
size and igraph label size according to the new axis ranges.jam_igraph()
when vertex.size
is defined alongside
V(g)$size, and node_factor
. It appears not to apply the size
properly.mem_enrichment_heatmap()
new option for dot plot format,
based upon enrichplot::dotplot()
that sizes each dot by the
number of genes present.multiEnrichMap()
remove default topEnrichSources
and topEnrichSourceSubset
which throw errors when not
using MSigDB data.topEnrichBySource()
and topEnrichListBySource()
should
be able to accept enrichResult
as input, and return enrichResult
and not data.frame
which is understandably lossy.
I need to understand the proper method for creating a subset
of an enrichList
object, including its internal data.topEnrichListBySource()
workflow.mem_gene_path_heatmap()
, so the pathway names are rows.mem
to be convenient for function examples,
and testthis test suite.edge_bundling="connections" should also allow render_groups=TRUE
to work, by returning the "nodegroups"
required for that step.
It should probably filter out singlet nodes by default, since the typical use case is "nodeset-to-node" for Cnet plots.
Priority: high
Status: Implemented, early active testing of usability and functionality
Useful to improve readability/aesthetics of collapsed Cnet plots, especially Cnet plots with many gene nodes where it is difficult to tell which pathway clusters are connected to each gene.
jam_igraph()
(must be done inside jam_plot_igraph()
)Consider silently returning the igraph
object plotted
where the vertex, edge, and graph attributes are updated
to the values used at runtime. For example, if user overrides
any attributes, those attributes will be present in the
object returned, so the next iteration someone could
just call jam_igraph()
without any custom attributes
and it would produce the same plot again.
See https://igraph.org/r/doc/plot.common.html
and igraph::igraph_options()
jam_igraph()
and jam_plot_igraph()
Priority: high
Status: Implemented
This task involves making edge bundling accessible as a simple option during plotting, to prevent having to run 3 or 4 functions:
jam_igraph()
with hidden edges
bundle_node_edges()
to display edges on top of nodesjam_igraph()
with hidden edges, nodes with solid white
color so they fully cover edges.jam_igraph()
with hidden edges, to display nodes on top
of bundled edges while allowing nodes to have alpha transparency
Note there is a package based on ggraph
that implements
edge bundling - if jam_ggraph()
is going to be our future,
maybe we should implement edge bundling using a similar approach
used by that R package.
plot_cnet_heatmaps()
to multienrichjamPriority: high
plot_cnet_heatmaps()
is in development, and arranges expression
heatmaps around a central Cnet plot, using genes in each cnet
cluster. It is intended to be used with Cnet clusters from
collapse_mem_clusters()
, by-product of mem_plot_folio()
.This figure seems very useful because it integrates expression changes alongside gene-pathway connections.
The multienrichment workflow would likely become:
multiEnrichMap()
mem_plot_folio()
plot_cnet_heatmap()
jam_igraph()
Priority: low
igraph:::plot.communities()
with mark.groups
Value is reinforcing node groups with a boundary. In testing, the boundary actually made plots look more complex. And with simple plots, it does not seem necessary since nodes are already well-spaced.
multiEnrichMap()
Priority: medium
Rows are pathways, columns are enrichments, values are the number of genes involved in enrichment.
Consider a matrix whose cells contain delimited gene symbols
Useful to apply filtering at matrix-level for pathways that meet enrichment P-value and gene count thresholds.
Priority: medium
reorderIgraphNodes()
all else should be sorted left-to-right (or user-defined default order)
it is visually confusing when tall-skinny nodes are sorted left-to-right
Useful to automate the ordering of node colors
multiEnrichMap()
Priority: low
multiEnrichMap()
,
as an alternative to using topEnrichBySource()
.Users can currently perform this subset step before running
multiEnrichMap()
.
multiEnrichMap()
multiEnrichMap()
does not filter by number of
genes involved in enrichment, it only filters by enrichment P-value.
New argument min_count
is applied only when topEnrichN
is used,
but nothing else downstream is aware of filtering by min_count
.
The corresponding argument in mem_plot_folio()
is
min_set_ct_each
, which requires a set (pathway) to contain
at least this many entries in at least one enrichment result
which also meets p_cutoff
criteria for enrichment P-value.Priority: low
mem_plot_folio()
and subsequent plots, optional argument
highlight_genes
which would effectively hide all gene labels
except highlight_genes
-- to help especially crowded plots.
Option 1: User-supplied genes
jam_igraph()
to hide/display relevant node labelsplot_cnet_heatmap()
could label the heatmap rows using anno_mark()
Useful in Cnet plots with too many genes to label, it allows only a subset of genes to be highlighted. Will become high priority if a manuscript decides to use this technique.
mem_plot_folio()
Priority: medium
mem_plot_folio()
once then be able to plot
any component separately. Would help keep all plots in sync
with the settings used.Design idea: List format
Named by type of output:
gene-pathway heatmap
collapsed cnet igraphs
cnet exemplar igraphs
each cnet cluster igraph
Each type of output contains a list
of relevant components
Priority: low
igraph
plots.jam_ggraph()
?
Test scatterpie
R package which implements pie
node shapes for use in ggraph. Unsure the data content
requirement.
reorderIgraphNotes()
reorderIgraphNotes()
reorderIgraphNodes()
when it encounters attributes with multiple
colors per node, such as "pie.colors"
and "coloredrect.colors"
,
calls avg_colors_by_list()
to generate one blended color per node,
then it sorts those colors using sort_colors()
. However, the
color order ultimately does not match the order in the color legend,
and other plots such as heatmaps.data.frame
where each color is in a separate column.
Then convert each column to a factor whose levels match the color
order from colorV
(argument to multiEnrichMap()
). The end result
should sort nodes consistent with the order of colors.colorV
. Therefore if any color
gradient is applied to nodes with nodeType="gene"
, this process
will not work.Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.