nwplot

Plot a network

Syntax

nwplot
[netname] 
[if]
[, node_options
label_options
edge_options
arrow_options
layout_options
other_options
export_options
twoway_options]
   
size(varname [,node_sub]) size of the nodes
labelopt(marker_label_options) options for look of node labels (e.g. size, color)

Description

This command plots a network. It gives a lot of flexibility to control all elements in a network plot. Furthermore, it is compatible with schemes() and accepts all twoway_options.

This example generates a random network and plots it. Because no netname is given, the command refers to the current network.

. nwclear
. nwrandom 20, prob(.2)
. nwplot

One can change the layout where nodes should be plotted:

. nwplot, layout(mds)
. nwplot, layout(circle)
. nwplot, layout(grid)
. nwplot, layout(grid, columns(20))
. nwplot, layout(kk)
. nwplot, layout(hierarchy)
. nwplot, layout(bipartite)
. nwplot, layout(bipartite, vertical)

Or obtain coordinates from layout and plot with coordinates. The option nodexy can be used to write your own network layout functions, return coordinates and plot a network with these coordinates. Because generate() and nodexy() are a matched pair - one exports the node coordinates a layout produced, the other forces a later plot to reuse them - this is also how to plot several different networks (e.g. the same set of people observed at several waves) at identical node positions, so the reader can compare panels directly instead of re-deriving a fresh, unrelated layout for each one:

. nwplot, gen(xcoord ycoord)
. replace xcoord = .2 if _n < 5
. nwplot, nodexy(xcoord ycoord)

. * fixed coordinates across two waves of the same network
. nwplot wave1, generate(x1 y1)
. nwplot wave2, nodexy(x1 y1)

interactive opens the plot in a browser alongside the usual static plot: drag nodes to reposition them, edit the color/shape legend (an edit applies to every node sharing that color/ shape key, not just one node - the same discrete legend model color()/symbol() already use), edit the edge color/pattern legend the same way, and adjust node-size/edge-width factors with two sliders. A button exports the picture as it stands, legend included, as a PNG image. The buttons open a save dialog in the native viewer (on Windows, macOS and Linux) and download the file in an ordinary browser tab. Two buttons in the browser save the edits as CSV files; feed them back with importcoords() (paired with nodexy(), same matched-pair idea as generate()/ nodexy() above) and edgeimport():

. nwplot flomarriage, generate(x y) color(wealth) interactive
. * drag nodes / edit the legend in the browser, then save both CSVs, then:
. nwplot flomarriage, nodexy(x y) importcoords("nodes.csv") edgeimport("edges.csv") color(wealth)

How the bring-back works: node positions come from the CSV through nodexy(); node colors and shapes are the legend edits, matched to the nodes by row. The size slider in the view is a multiplier on the view’s own starting size and the view draws in screen pixels, so a slider value of 1 corresponds to about nodefactor(0.2) in the static graph. Without nodefactor(), nwplot therefore uses 0.2 times the saved slider value, which reproduces the proportions of the view (a slider value of 1.85 gives nodefactor(0.37)); an explicit nodefactor() (or edgefactor()) always wins over the saved values. In the interactive legend, the shape drop-down of a colour group reads “mixed” when the nodes of that group have different shapes (for example when symbol() is a second variable); choosing a shape there sets all nodes of the group. The CSV format is unchanged.

The view draws y upward, as the static plot does, for every layout and for nodexy() (with nodexy(Lon Lat) the map is upright), and the saved CSV holds the same y, so a saved layout comes back in the same orientation. With edgesize() the view maps the tie values linearly onto line widths of 1 to 8 pixels (all ties 3 pixels without edgesize(); the static plot uses the same 1 to 8 mapping); the edge-width slider is a multiplier on top. Arrowheads shrink with thin ties and are capped for thick ones; the arrow-size slider multiplies on top. edgeimport() accepts the edge file of a directed or an undirected network (the view lists an undirected tie once).

importcoords()/edgeimport() must be run against the same network, same size, as the interactive view they came from (row order is how nwplot matches an edit back to a node/tie, the same way nodexy()/label() already do) - re-export from interactive rather than reusing an old CSV after the network or an if/in restriction changes. Node size is not yet individually editable in the interactive view; the size-factor slider maps onto nodefactor() instead.

Arrow heads are plotted when a network is directed. Furthermore, the command notices if a dyad is mutually or asymmetrically connected (see nwdyads). By default, asymmetrically connected dyads are represented as a straight line, whereas mutually connecetd dyads are represented as two curved lines. However, one can overwrite this and show all ties as curved lines.

. nwplot, arcstyle(automatic)
. nwplot, arcstyle(straight)
. nwplot, arcstyle(curved)
. nwplot, arcbend(0.3) arcsplines(20)

Almost all elements in a network plot can be easily made bigger or smaller using factors:

. nwplot, nodefactor(2)
. nwplot, edgefactor(2)
. nwplot, arrowfactor(4)
. nwplot, arrowbarbfactor(.2)
. nwplot, nodefactor(2) edgefactor(4) arrowfactor(2) arrowbarbfactor(.2)

Colors, symbols and size of nodes can be changed accoring to a varname. Furthermore, the palettes used for display can be changed as well.

. nwwebuse glasgow, nwclear
. nwplot glasgow1, color(smoke1)
. nwplot, color(smoke1, colorpalette(red yellow cyan))

. nwplot glasgow1, symbol(sport1)
. nwplot glasgow1, symbol(sport1, symbolpalette(T S))

. nwplot glasgow1, size(alcohol1)
. nwplot, size(alcohol1, forcekeys1(1 5 10 20))

. nwplot glasgow1, size(alcohol1) color(smoke1) symbol(sport1)

nwcommands ships three schemes purpose-built for network plots - s1network, s2network, and s3network - each giving node fill and edge line colors that are visually distinct by default (an ordinary Stata scheme such as the default stcolor typically does not, since a single data series’ marker and connecting line usually should match - reasonable for an ordinary statistical graph, not for a network plot). nwplot defaults to s1network unless scheme() is specified explicitly.

. nwplot, scheme(s1network)
. nwplot, scheme(s2network)
. nwplot, scheme(s2mono)
. nwplot, size(alcohol3) color(smoke3) symbol(sport3) scheme(s1network)
. nwplot, size(alcohol3) color(smoke3) symbol(sport3) scheme(economist)
. set scheme s2network

This example calculates the shortest path between two nodes (medici and peruzzi) and uses this path to color the edges of the original network and change the size of the edges on this path.

. nwwebuse florentine, nwclear
. nwpath flomarriage, ego(medici) alter(peruzzi) generate(sp)
. nwplot flomarriage, edgecolor(sp_1, legendoff) edgesize(sp_1, legendoff) edgefactor(5)

Another example that changes the size and color of edges.

. nwwebuse gang, nwclear
. nwplot
. nwplot gang, edgesize(gang)
. nwgenerate blood = (gang==4)
. nwplot blood
. nwplot gang, edgesize(gang) edgecolor(blood)

This is how to control the legend of the plot. All options that can be used for twoway legends are valid.

. nwplot gang, size(Arrests, forcekeys(5 10 20)) legendopt(on pos(3) cols(1))

Because nwplot uses twoway plots one can use all general twoway options to e.g. control the title of a plot.

. nwwebuse florentine, nwclear
. nwplot flomarriage, edgecolor(flobusiness) title("Florentine Marriages", color(red) size(huge))

Here, the nodes are plotted with the node labels saved with the network:

. nwplot flobusiness, lab

More generally, one can use any varname as node labels. The next example, does the same as the previous command, but shows how one could use node labels stored elsewhere:

. nwplot flobusiness, label(wealth)

The look and feel of node labels is changed with labelopt():

. nwplot flobusiness, label(wealth) labelopt(mlabsize(huge) mlabcolor(red))

The command draws on normal scatter plots to plot nodes. Once can send all sorts of options directly to these underlying scatter plots. Here, the color and symbol of nodes is overwritten.

. nwplot flomarriage, scatteropt(mfcolor(green) msymbol(D))
. nwplot flomarriage, lineopt(lwidth(10) lcolor(green))

The next example shows how to only plot the largest component of the network.

. nwwebuse glasgow, nwclear
. nwcomponents glasgow1, lgc generate(large)
. nwplot glasgow1 if large == 1

Alternative to display the largest component only:

. nwwebuse glasgow, nwclear
. nwplot glasgow1, layout(,lgc)

Publication-quality vector export. export() saves the plot directly to a file, inferring the format from the extension - exactly what a manual graph export call afterward would do, since nwplot produces an ordinary Stata graph and never replaces or bypasses it. SVG and PDF are both scalable vector formats: the plot stays crisp at any zoom level or print size, and both open cleanly in standard vector-graphics editors (e.g. Adobe Illustrator, Inkscape) for further touch-up - node/edge/label elements remain separate, editable objects rather than a fixed-resolution image.

. nwplot flomarriage, export("flomarriage.svg")
. nwplot flomarriage, export("flomarriage.pdf") replace

Raster formats (PNG, TIF, …) are also supported the same way; exportopt() passes options straight through to the underlying graph export call, most commonly width()/height() to control resolution:

. nwplot flomarriage, export("flomarriage.png") exportopt(width(2000))

The graph itself is unaffected by export() - it remains the normal, currently active Stata graph afterward, so the Graph Editor, stata graph save, and a second graph export in a different format all continue to work exactly as they would without export().

Supported network types

Binary: yes. Weighted: yes. On a valued network the widths of the edges follow the tie values by default (as edgesize(network) with 1 to 4 units; binary switches it off; edgesize() sets the 1 to 8 range and any other network). The values never change the colour of an edge unless you ask for it with edgecolor(). Signed: yes - a network with negative ties draws positive ties solid navy and negative ties dashed cranberry, with a legend, and the width follows the absolute value (nosign switches the colours off; binary keeps the colours and drops the widths). The layouts kk (the default) and frucht use the tie values as strengths on a valued network (see Valued networks and layouts; binary switches it off), the other layouts use the ties only. Directed: yes - this is the command’s native case; arrows are drawn automatically, and reciprocated (mutual) dyads are curved apart from their asymmetric counterparts by default (arcstyle(automatic)) so both directions of a tie remain visible rather than overlapping. Undirected: yes, the default. Two-mode: yes - plots the nodes and the ties between the modes; the modes get a symbol (circle, diamond) and a colour each, with a legend, unless color() or symbol() is given; layout(bipartite) puts the two modes in two rows (igraph::layout_as_bipartite). Self-loops: not rendered - a self-loop currently has no visible effect on the plot (a zero-length tie), a known limitation recorded in the package’s own visualization roadmap rather than fixed here.

Stored results

nwplot is rclass.

  • Macros:
  • r(export) filename actually passed to export(), if specified
  • r(fname) path of the interactive HTML page written by interactive
  • r(interactive) same as r(fname)
  • r(edgewidth) values, edgesize or binary: how the edge widths were set

  • Scalars:
  • r(signcolor) 1 if the sign colours (solid navy, dashed cranberry) were used
  • r(modesymbols) 1 if the two modes of a two-mode network got their own symbols

See also


nwcommands version 3.17.6, 9 November 2026 (check your installed version)


Back to top

nwcommands is free software under the GNU General Public License, version 3, as are the model packages nwsaom, nwergm, nwdynam and nwrem. Citing and licenses · Get help · GitHub. Issues with the core go to the nwcommands repository; issues with a model package go to that package's own repository.

This site uses Just the Docs, a documentation theme for Jekyll.