Skip to content

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.

StageWhat the respondent does
name_generatorTypes names in answer to a prompt, or picks them from a list
name_interpreterAnswers the same questions about each person (radio, multiselect, number, text)
dyad_censusSays, for every pair of people, whether they know each other: n(n-1)/2 pairs, one at a time, with a progress bar
sociogramDrags 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:

yaml
phases:
  order: [your_network, annotation]
  your_network:
    type: prestudy
    file: surveys/your-network.json

The page file holds the scheme, shown here in YAML. The same keys work in annotation_schemes:

yaml
- 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
OptionDefaultMeaning
stagesrequiredThe stages, in order. A name_generator must come before any other stage
stage_layoutstepssteps shows one stage at a time, stacked shows them all at once
label_requirementnone{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

OptionDefaultMeaning
min_alters0People this stage needs before the respondent can go on
max_altersnoneMost people this stage accepts
rosternoneNames to pick from instead of typing: strings, or {id, name}
roster_fieldnoneAn item field holding the list (annotation items only)
setsnoneAttributes given to everyone named in this stage, such as {support: true}
placeholderFirst name or nicknamePlaceholder 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

OptionDefaultMeaning
promptDo {a} and {b} know each other?{a} and {b} are replaced by the two names
relationnoneName of the relation, when a study records more than one kind of tie
yes_label, no_labelYes, NoAnswer labels
strength_labelsnoneAsks how strong the tie is instead of yes, with one button per label plus no_label
strength_variablestrengthTie 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

OptionDefaultMeaning
relationnoneThe relation the lines record
allow_tiestruefalse for a placement-only canvas
rings3Concentric 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:

json
{
  "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

bash
python -m potato.export --config config.yaml --format ego_network --output out/
FileContents
egos.csvOne 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.csvOne row per alter: alter_id, named_in, x, y, degree, and one attr_<name> column per attribute
edges.csvOne row per tie: source_alter, target_alter, relation (tie when unnamed), and tie_<name> columns such as tie_strength
graphml/<user>__<item>.graphmlOne 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 CanvasPotato
EgoFormA survey page, with the introduction panel as a heading
Information (text items)A pure_display page, with Markdown reduced to plain text
NameGenerator, NameGeneratorQuickAddname_generator stages, one per prompt
NameGeneratorRostername_generator with a roster read from the protocol's CSV or JSON asset
additionalAttributes on a promptsets on that name generator
Extra fields on the add-person formA name_interpreter stage right after the name generator
AlterFormname_interpreter
OrdinalBin, CategoricalBinname_interpreter with one radio question per prompt
DyadCensus, OneToManyDyadCensusdyad_census, with relation from the edge type
TieStrengthCensusdyad_census with strength_labels from the edge variable's options
Sociogramsociogram, with concentricCircles as rings
minNodes, maxNodesmin_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.

bash
python potato/flask_server.py start examples/advanced/ego-network/config.yaml -p 8000

Quote "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

For implementation details, see the source documentation.