creates and prints a barplot (using matplotlib) for all values that an
    attribute can have, e.g. counts of POS tags for all token nodes in a
    document graph.

    docgraph : DiscourseDocumentGraph
        the document graph from which we'll extract node/edge attributes
    elements : collections.Iterable
        an iterable of nodes or edges
    attribute : str
        name of the attribute to count (e.g. ``penn:pos``)
    ignore_missing : bool
        If True, doesn't count all those elements that don't have the given
        attribute. If False, counts them using the attribute ``NOT_PRESENT``.

def plot_attribute_distribution(docgraph, elements, attribute,
                                ignore_missing=True):
    '''
    creates and prints a barplot (using matplotlib) for all values that an
    attribute can have, e.g. counts of POS tags for all token nodes in a
    document graph.

    docgraph : DiscourseDocumentGraph
        the document graph from which we'll extract node/edge attributes
    elements : collections.Iterable
        an iterable of nodes or edges
    attribute : str
        name of the attribute to count (e.g. ``penn:pos``)
    ignore_missing : bool
        If True, doesn't count all those elements that don't have the given
        attribute. If False, counts them using the attribute ``NOT_PRESENT``.
    '''
    value_counts = Counter()

    if isinstance(elements, GeneratorType):
        elements = list(elements)

    if isinstance(elements[0], (str, unicode, int)):
        element_type = 'node'
    elif isinstance(elements[0], tuple):
        element_type = 'edge'
    else:
        raise ValueError('Unknown element type: '.format(element[0]))

    if element_type == 'node':
        # count all nodes with the given attribute
        for element in elements:
            try:
                value_counts[docgraph.node[element][attribute]] += 1
            except KeyError:
                if not ignore_missing:
                    value_counts['NOT_PRESENT'] += 1
    else: # element_type == 'edge':
        # count all edges with the given attribute
        for element in elements:
            source, target = element
            try:
                for edge in docgraph.edge[source][target]: # multidigraph
                    value_counts[docgraph.edge[source][target][edge][attribute]] += 1
            except KeyError:
                if not ignore_missing:
                    value_counts['NOT_PRESENT'] += 1

    sorted_value_counts = sorted(value_counts.iteritems(), key=itemgetter(1),
                                 reverse=True)

    # generate plot
    x = np.arange(len(sorted_value_counts))
    plt.bar(x, [attrib_count for attrib_name, attrib_count in sorted_value_counts])
    # set positions of the attribute value labels on the x-axis
    # (shifted to the right, words arranged upwards)
    _xticks = plt.xticks(
        x + 0.5,
        [attrib_name for attrib_name, attrib_count in sorted_value_counts],
        rotation=90)
    plt.show()