Package: alph
alph-altair for your graphA Python library usingAltairfor declarative, data-driven network visualisation.WhyTidy, legible graph visualisations can be elusive. Alph helps by bringing together effective styling, layout and pruning options from across the Python ecosystem.How it worksGet your data into a NetworkX GraphPick a network layout function, or bring your own node coordinatesDefine node and edge style attributesPlot using a simple function callBest bet is probably to dive straight into theexamples, and come back to the API documentation below as needed.Featuresplot any NetworkX Graphsupport for any layout expressed as a NetworkXposstructure (a dict like{node_id: (x,y), ...})several readily accessible and tuneable layout functions (seeexample)Altair-style data driven node and edge styling - size, colour, stroke, opacity, scales, conditionals and moreconvenience args for node labels, halosexperimental 1-level "combo" node supportInstallationMinimalpip install alphRecommendedfor graphviz layout support, install graphviz on your platform - e.g.brew install graphvizon Mac,sudo apt install libgraphviz-dev graphvizon Colab, Debian, Ubuntu etc - ordownload the installerInstall alph with graphviz support:pip install "alph[graphviz]"Install the ForceAtlas2 layout library from our fork, along with cython for speeduppip install cython "git+https://github.com/connectedcompany/forceatlas2.git"Why is the ForceAtlas2 install separate?ForceAtlas2is a classic,
user feedback led layout algorithm from theGephiteam, and theForceAtlas2 libraryimplementation is an excellent, performant Python port. There are two things to be aware of:GPL licence- the ForceAtlas2 library, and some of the works it is derived from, are GPL licensed -
hence care is needed when distributing and linking to it. We thus intend to keep its install optional
long term. Since alph uses a plugin design for layout providers, this is straightforward for us to
accommodate, and maintain explicit separation for use cases where GPL is an issue.Our fork- recently, releases of the library have been sporadic - though there is stated intent for
regular maintenance to resume. In the meantime, we've created a temporary fork to be able to roll in
changes. Currently, our fork incorporates a simple change that enables deterministic layouts.UsageSimply call thealphfunction with desired options.Minimally, given a weighted network G:from alph import alph

G = ...
alph(G, weight_attr="weight")ExamplesSeeexamples. Here's an overview:Some of the supported layouts (from thelayouts gallery example):Use of geolocation coordinates for graph layout, (from theflight routes example):Basic styling (from thestyling example):A styled interaction network (from thedolphins example):"Combo"-style layout (experimental) - category-driven node grouping with edge weight aggregation, from theLes Mis example:APISupported layout functionsNetworkX layouts: Spring, Fruchterman-Reingold, etcNetworkX-wrappedgraphviz layouts:
dot, neato etc. You can useargsfor specific layouts - for example, for neato:args="-Goverlap=scale -Gstart=123"Gephi ForceAtlas2 based on theforceatlas2 Python implementation-
seelayout.pyfor configuration options, andthis paperfor more detailForceAtlas implementation withinscikit-networkAny other that returns a NetworkX-style node positions dictionarySupported argumentsargtype(s)defaultdescriptionGNetworkx Graphgraph to visualiseweight_attrstredge weight attribute, for weighted graphslayout_fnfunctionForceAtlas2Function that, given a graph, returns a layoutnode argsdictSee belowedge argsdictSee belowcombo_group_bystr or listAttribute to use to create grouped combo nodescombo_layout_fnfunctionFruchterman-ReingoldLayout function for combo nodescombo_node_argsdictSee belowcombo_edge_argsdictSee belowcombo_edge_weight_agg_attrdictAttribute to use to weigh combo edges; if set, overrides weight_attr. Can use values given via combo_edge_agg_attrs. If not set and weight_attr not given, falls back to simple edge count.combo_edge_agg_attrsdictPandas groupby-style dict, describing how to aggregate edge attributes that span nodes - for example{"combo_edge_attr_name": ("edge_attr_name", "sum")}combo_edge_weight_thresholddictDrop edges below this weightinclude_edgeless_combo_nodesdictWhether or not to incorporate disconnected combo nodescombo_node_additional_attrsdictAttributes to add to combo nodesedge_node_additional_attrsdictAttributes to add to combo node edges, like{"edge_attr_name": agg_fn}; agg fn is applied across all attr values for edges that link grouped nodescombo_empty_attr_actiondrop, group or promotedropWhat to do with nodes that have an empty value for the combo_group_by attributecombo_size_scale_domain2-item list or tuple[0, 25]Lower/upper bound of num nodes to apply to combo node size rangecombo_size_scale_range2-item list or tuple[6**2, 180**2]Combo node size rangecombo_inner_graph_scale_factorfloat0.6Scale down inner graph to fit inside combo nodes by this factor - normally <1non_serializable_datetime_formatstr%d %b %YFormat string for non-serialisable date / time types that otherwise break Altairwidthint800Figure width (px)heightint600Figure height (px)prop_kwargsdictOptional properties such as titlepaddingintPadding inside figure edges. No node centres will be placed outside this boundary.nodes_layer_paramsselection or otherAltair params to be added to the nodes layer via.add_params()- typically a selectionNode argsargtype(s)defaultsizeint, alt.*400tooltip_attrslistfillstr, alt.*#000opacityfloat, alt.*1strokestr, alt.*#565656strokeWidthint, alt.*0halo_offsetinthalo_opacityfloat, alt.*1halo_strokestr, alt.*#343434halo_strokeWidthint, alt.*2label_attrstrlabel_offsetint6label_sizeint10label_colorstrblackEdge argsargtype(s)defaultweight_attrstrweightcolorstr, alt.*#606060opacityfloat , alt.*alt.Size(weight_attr, scale=alt.Scale(range=[0.3, 1])if weighted,1otherwisestrokeWidthint, alt.*alt.Size(weight_attr, scale=alt.Scale(range=[0.1, 5])if weighted,2otherwiseTipsGet to know your layout algos - especially the 2-3 most used ones. They can have a dramatic
effect on the results. A combination of FA2, Spring and Fruchterman is extremely versatile
if set up right.Passseedto layout functions where possible, for repeatable layoutsSet padding to ensure node elements stay within figure boundariesKnown limitationsNodesizeattribute does not support all Altair options - currently onlyalt.valueandalt.Sizewith lineardomainandrangescales. More can be
added as needed.This is a design choice, made to not burden the user with calculating things like
label and halo positions when node sizes vary. Will review this tradeoff based
on in-use experience.One combo level currently supportedSee alsonx-altairis a nice project that takes a slightly
different approach to combining NetworkX and Altair for network viz.