Ego Networks: Name Generators, Interpreters, Dyad Census and Sociograms
Collect personal networks in Potato with name generators, name interpreters, a dyad census and a sociogram, import Network Canvas protocols, and export GraphML.
New in v2.12.0
ego_network collects a personal (egocentric) network, a standard object of social network analysis. The respondent, the ego, names people (alters), answers questions about each of them, says which of them know each other, and places them on a map. The scheme works on a survey page, which is how most personal-network studies run it, and on annotation items, where a coder records the network a document describes.
One scheme holds an ordered list of stages. Every stage works on the same set of alters, so a person named in the first name generator appears in every later stage.
| Stage | What the respondent does |
|---|---|
name_generator | Types names in answer to a prompt, or picks them from a list |
name_interpreter | Answers the same questions about each person (radio, multiselect, number, text) |
dyad_census | Says, for every pair of people, whether they know each other: n(n-1)/2 pairs, one at a time, with a progress bar |
sociogram | Drags people around a canvas and clicks two people to add or remove a line between them |
By default the stages are shown one at a time, each with its own Back and Next buttons and a row of step buttons. stage_layout: stacked shows them all on the page at once.
Configuration
On a survey page, list the page under phases and put the scheme in its file:
phases:
order: [your_network, annotation]
your_network:
type: prestudy
file: surveys/your-network.jsonThe page file holds the scheme, shown here in YAML. The same keys work in annotation_schemes:
- annotation_type: ego_network
name: personal_network
description: People you talk to
label_requirement:
required: true
stages:
- type: name_generator
id: discuss
title: Important matters
prompt: >-
Looking back over the last six months, who are the people you talked
to about matters that are important to you?
min_alters: 1
max_alters: 8
sets: {discuss: true}
- type: name_generator
id: help
title: Practical help
prompt: Who would you ask for help if you were ill for a couple of weeks?
sets: {help: true}
- type: name_interpreter
id: about
title: About each person
required: true
questions:
- name: closeness
type: radio
description: How close do you feel to {name}?
labels:
- {name: very, text: Very close}
- {name: somewhat, text: Somewhat close}
- {name: not, text: Not close}
- name: years_known
type: number
description: About how many years have you known {name}?
min: 0
max: 100
required: false
- type: dyad_census
id: know
prompt: Do {a} and {b} know each other?
- type: sociogram
id: map
rings: 3| Option | Default | Meaning |
|---|---|---|
stages | required | The stages, in order. A name_generator must come before any other stage |
stage_layout | steps | steps shows one stage at a time, stacked shows them all at once |
label_requirement | none | {required: true} stops the page from continuing until the network is complete |
Every stage takes type, id (a letter followed by letters, digits, _ or -, defaulting to <type>_<n>), title, prompt and instructions.
Name generators
| Option | Default | Meaning |
|---|---|---|
min_alters | 0 | People this stage needs before the respondent can go on |
max_alters | none | Most people this stage accepts |
roster | none | Names to pick from instead of typing: strings, or {id, name} |
roster_field | none | An item field holding the list (annotation items only) |
sets | none | Attributes given to everyone named in this stage, such as {support: true} |
placeholder | First name or nickname | Placeholder of the name box |
Typing a name already on the list is refused with a message, so one person is not recorded twice. A later name generator lists the people named earlier under "Named earlier", and the respondent adds anyone who also belongs there with one click. The alter keeps one ID and records every generator that named them. Removing a person from the only generator that named them removes them from the network, with their answers and ties.
Name interpreters
A name_interpreter stage takes questions (required) and required, the default for its questions. Each question has name (unique across the scheme), type (radio, multiselect, number or text), description ({name} is replaced by the person's name), labels for radio and multiselect (strings or {name, text}, where name is what is stored), required, and min, max and step for numbers. The page shows one card per person with every question on it.
Dyad census
| Option | Default | Meaning |
|---|---|---|
prompt | Do {a} and {b} know each other? | {a} and {b} are replaced by the two names |
relation | none | Name of the relation, when a study records more than one kind of tie |
yes_label, no_label | Yes, No | Answer labels |
strength_labels | none | Asks how strong the tie is instead of yes, with one button per label plus no_label |
strength_variable | strength | Tie attribute the strength answer is stored under |
The census shows one pair at a time and moves to the next unanswered pair after each answer. "All pairs" lists every pair with its answer, and clicking one goes back to it.
Sociogram
| Option | Default | Meaning |
|---|---|---|
relation | none | The relation the lines record |
allow_ties | true | false for a placement-only canvas |
rings | 3 | Concentric circles drawn behind the people, from 0 to 6 |
Positions are saved as fractions of the canvas width and height. A line drawn on the sociogram and a census answer for the same relation are the same record, so drawing a line between two people sets their census answer to yes, and removing it sets it to no.
Every control is a button or a text box reachable with Tab. On the sociogram, Tab moves between people, Enter selects one and opens a list of everyone else to add or remove ties, arrow keys move the focused person (Shift moves further), and Escape closes the list.
Data format
The answer is stored as one JSON string:
{
"alters": [{"id": "a1", "name": "Ann", "named_in": ["discuss", "help"]},
{"id": "a2", "name": "Bob", "named_in": ["discuss"]}],
"attributes": {"a1": {"discuss": true, "help": true, "closeness": "very"}},
"ties": [["a1", "a2"]],
"positions": {"a1": [0.42, 0.31], "a2": [0.7, 0.55]},
"census": {"a1|a2": true},
"tie_attributes": {}
}Alter IDs are a1, a2 and so on, in the order people were named, and a deleted ID is not reused. A tie is [a, b], or [a, b, relation] when the stage names a relation.
Export
python -m potato.export --config config.yaml --format ego_network --output out/| File | Contents |
|---|---|
egos.csv | One row per network: network_size, n_ties, possible_ties, density, isolates, components, relations, and complete with incomplete_reason checked against the scheme's own rules |
alters.csv | One row per alter: alter_id, named_in, x, y, degree, and one attr_<name> column per attribute |
edges.csv | One row per tie: source_alter, target_alter, relation (tie when unnamed), and tie_<name> columns such as tie_strength |
graphml/<user>__<item>.graphml | One GraphML file per network, with alters as nodes and ties as undirected edges |
The ego is not a node in these files. Density, components and degree are computed over alter-alter ties, and two people tied on two relations count as one connected pair.
Alter names
The names respondents type identify people who have not agreed to take part in the study, so the ego_network export leaves them out and writes the pseudonymous IDs only. --option export_names=true includes them.
The names are still in the raw output (annotation_output/) and in the general exports (csv, jsonl), which write the stored JSON as it is. Ask respondents for first names or nicknames, and handle those files as identifiable data.
Completeness
With label_requirement: {required: true}, the page will not continue while a name generator has fewer than min_alters people, a required name-interpreter question is unanswered for someone, or a dyad census has unanswered pairs, and it says which. Inside the widget, Next stays on a name generator until it has min_alters people, whether or not the scheme is required.
Importing a Network Canvas protocol
potato import -f network_canvas -i my-study.netcanvas -o my-study/ reads a Network Canvas protocol, either the .netcanvas file saved in Architect or a bare protocol.json. Ego forms become pages of ordinary questions, and the network stages for each node type become one ego_network question:
| Network Canvas | Potato |
|---|---|
EgoForm | A survey page, with the introduction panel as a heading |
Information (text items) | A pure_display page, with Markdown reduced to plain text |
NameGenerator, NameGeneratorQuickAdd | name_generator stages, one per prompt |
NameGeneratorRoster | name_generator with a roster read from the protocol's CSV or JSON asset |
additionalAttributes on a prompt | sets on that name generator |
| Extra fields on the add-person form | A name_interpreter stage right after the name generator |
AlterForm | name_interpreter |
OrdinalBin, CategoricalBin | name_interpreter with one radio question per prompt |
DyadCensus, OneToManyDyadCensus | dyad_census, with relation from the edge type |
TieStrengthCensus | dyad_census with strength_labels from the edge variable's options |
Sociogram | sociogram, with concentricCircles as rings |
minNodes, maxNodes | min_alters (first prompt), max_alters (each prompt) |
Option values are kept as the stored answers, so exports carry the same codes as the protocol. Skip logic on ego variables becomes page show_when, and a skip to a FinishSession stage becomes exit_when on the page before, so a participant who declines consent leaves the study there. Protocols with translations import in English unless you pass --survey-language.
Some things change. All network stages for one node type share one page, placed where the first of them was, so a network stage that came after other pages comes before them, and the import warns about each one. Dragging people into bins becomes one choice per person, with the same stored values. Skip logic that tests node or edge data, AlterEdgeForm, Narrative, Geospatial and the pedigree stages, date pickers, media items and interviewer notes are listed in IMPORT_REPORT.md and not imported.
Example
examples/advanced/ego-network/ runs the scheme twice: as a survey page before the task, for the participant's own network, and as the annotation task, where coders record the network each interview excerpt describes.
python potato/flask_server.py start examples/advanced/ego-network/config.yaml -p 8000Quote "Yes" and "No" in label lists, because YAML reads them unquoted as booleans, and write stage_layout: stacked, not layout: stacked, since layout is the grid-placement mapping every scheme accepts.
Further Reading
- Survey Import - Network Canvas and six other questionnaire formats
- Multi-Phase Workflows - Survey pages before and after the task
- Cultural Domain Analysis - Free lists and triad tests for the same respondents
For implementation details, see the source documentation.