Source code for src.plot_functions

"""

==============================================================
Functions for Plotting, (:mod:`f_abm.src.plot_functions`)
==============================================================

Description
-----------

    This is the module that takes care of all the plotting, whether it is for opinion distributions (histograms), or
    digraphs, or whatever it is required.

Functions
---------

    - plot_digraph
    - plot_opinions
    - plot_histogram
    - plot_inner_traits
    - plot_all_opinions

"""


import numpy as np
import matplotlib.pyplot as plt
import igraph as ig
from .auxiliary_functions import (matrix2digraph, opinion2color, histogram_classification)
from .digraph_creation import default_digraph


[docs]def plot_digraph(digraph=None, file_name=None, visual_style=None, close_figure=False, figure_size=(10, 7), figure_title='Underlying Digraph', title_font_size=20): """ Function to plot the digraph Parameters ---------- digraph: Digraph to be plotted, by default it is a simple ring digraph file_name: string that is the name of the file to be plotted visual_style: optional visual style close_figure: boolean determining if the figure must be closed figure_size: size of the figure to be produced figure_title: title of the plot title_font_size: size of the title Returns ------- """ if digraph is None: digraph = matrix2digraph(default_digraph(default_type=0)) if visual_style is None: # Get the edge weights edge_weights = digraph.es["weight"] color_dict = {1.0: "blue", -1.0: "red"} digraph.es["color"] = [color_dict[edge_weight] for edge_weight in edge_weights] visual_style = {"vertex_size": 0.1} if file_name is not None: fig = plt.figure(figsize=figure_size) ax = fig.add_subplot(111) ig.plot(digraph, target=ax, **visual_style, layout="circle") ax.set_title(figure_title, fontsize=title_font_size) plt.savefig(fname=file_name, format='png')
# ig.plot(digraph, target=file_name + ".png", **visual_style, layout="circle") # digraph_plot = ig.plot(digraph, **visual_style, layout="circle") # digraph_plot.save(file_name + ".png") # fig, ax = plt.subplots() # ig.plot(digraph, target=ax, **visual_style, layout="circle") # plt.show() # if close_figure: # print('Close digraph') # plt.close(fig)
[docs]def plot_opinions(opinion_evolution, agent_parameters, opinion_model, axes=None, file_name=None, close_figure=False, figure_size=(10, 7), figure_title='Opinion evolution', figure_x_label='Time steps', figure_y_label='Opinions', title_font_size=20, x_label_font_size=15, y_label_font_size=15): """ Function to plot the opinion evolution Parameters ---------- opinion_evolution: matrix with the opinion evolution data agent_parameters: parameters for each agent opinion_model: the label of the opinion model axes: the axes for the plot file_name: string that is the name of the file to be plotted close_figure: boolean determining if the figure must be closed figure_size: size of the figure to be produced figure_title: title of the plot figure_x_label: x label of the figure figure_y_label: y label of the figure title_font_size: size of the title x_label_font_size: x label text size y_label_font_size: y label text size Returns ------- Nothing """ # Get the number of agents num_agents = opinion_evolution.shape[0] num_steps = opinion_evolution.shape[1] if axes is None: fig = plt.figure(figsize=figure_size) ax = fig.add_subplot(111) else: ax = axes for id_agent in range(num_agents): ax.plot(opinion_evolution[id_agent], color=opinion2color(opinion_model, agent_parameters[id_agent])) ax.set_xlim([0, num_steps]) ax.set_ylim([-1.1, 1.1]) ax.set_title(figure_title, fontsize=title_font_size) ax.set_xlabel(figure_x_label, fontsize=x_label_font_size) ax.set_ylabel(figure_y_label, fontsize=y_label_font_size) if axes is None: plt.grid() # display the plot # plt.show() else: ax.grid() if file_name is not None: plt.savefig(fname=file_name, format='png') if close_figure: plt.close(fig)
[docs]def plot_histogram(ax, opinions, num_bins=10, histogram_title='Histogram of the opinions', file_name=None, close_figure=False, figure_size=(10, 7), figure_x_label='Opinions', figure_y_label='Count', title_font_size=20, x_label_font_size=15, y_label_font_size=15): """ This function creates and plots the histogram for a set of opinions Parameters ---------- ax: the axis where the histogram is plotted opinions: the set of opinions num_bins: the number of bins of the histogram, by default it is 10 histogram_title: title of the histogram file_name: string that is the name of the file to be plotted close_figure: boolean determining if the figure must be closed figure_size: size of the figure to be produced figure_x_label: x label of the figure figure_y_label: y label of the figure title_font_size: size of the title x_label_font_size: x label text size y_label_font_size: y label text size Returns ------- Nothing """ if ax is None: fig = plt.figure(figsize=figure_size) ax = fig.add_subplot(111) ax.grid() ax.hist(opinions, bins=np.linspace(-1.0, 1.0, num_bins+1), edgecolor='black') ax.set_xlim([-1.1, 1.1]) ax.set_ylim([0, opinions.shape[0]]) ax.set_title(histogram_title, fontsize=title_font_size) ax.set_xlabel(figure_x_label, fontsize=x_label_font_size) ax.set_ylabel(figure_y_label, fontsize=y_label_font_size) ax.set_axisbelow(True) if file_name is not None: plt.savefig(fname=file_name, format='png') if close_figure: plt.close(fig)
[docs]def plot_inner_traits(file_name='standard_inner_traits.npy', figure_size=(10, 7), figure_title='Inner Traits', figure_x_label='Average conformist parameter', figure_y_label='Average radical parameter', title_font_size = 20, x_label_font_size=15, y_label_font_size=15): """ Function to plot the inner traits for the Classification-based model Parameters ---------- file_name: name of the file that contains the inner traits figure_size: size of the figure to be produced figure_title: title of the plot figure_x_label: x label of the figure figure_y_label: y label of the figure title_font_size: size of the title x_label_font_size: x label text size y_label_font_size: y label text size Returns ------- Nothing """ all_inner_traits = np.load(file_name) # loads your saved array into variable all_opinions fig = plt.figure(figsize=figure_size) ax = fig.add_subplot(111) for inner_traits in all_inner_traits: av_con, av_rad = np.maximum(np.minimum(inner_traits.mean(axis=0), 1), 0) # Truncation is necessary to avoid problems with negative averages that produce non-existent colours # These negative averages may be produced by small numerical errors av_stb = 1 - (av_con + av_rad) ax.plot(av_con, av_stb, 'o', color=opinion2color(opinion_model='CB', agent_parameter=[av_con, av_rad])) ax.set_xlim([-0.1, 1.1]) ax.set_ylim([-0.1, 1.1]) # ax.set_title('All Inner Traits') ax.set_title(figure_title, fontsize=title_font_size) ax.set_xlabel(figure_x_label, fontsize=x_label_font_size) ax.set_ylabel(figure_y_label, fontsize=y_label_font_size) plt.grid() # display the plot plt.show()
[docs]def plot_all_opinions(file_name='standard_initial_opinions.npy', color_by_type=False, figure_size=(10, 7), figure_title='Agreement Plot of all Opinions', figure_x_label='mean(abs(opinions))', figure_y_label='mean(opinions)', title_font_size = 20, x_label_font_size=15, y_label_font_size=15): """ Function to plot a set of opinion distributions in the Agreement Plot Parameters ---------- file_name: name of the file that contains all the initial opinion distributions color_by_type: boolean specifying how to color the plot figure_size: size of the figure to be produced figure_title: title of the plot figure_x_label: x label of the figure figure_y_label: y label of the figure title_font_size: size of the title x_label_font_size: x label text size y_label_font_size: y label text size Returns ------- Nothing """ all_opinions = np.load(file_name) # loads your saved array into variable all_opinions if color_by_type: point_colors = [(0.16862745, 0.34901961, 0.76470588), (0.32941176, 0.54901961, 0.18431373), (0.82745098, 0.39607843, 0.50980392), (0.94509804, 0.56078431, 0.00392157), (0.39607843, 0.05098039, 0.10588235)] else: point_colors = [(0.16862745, 0.54901961, 0.10588235), (0.16862745, 0.54901961, 0.10588235), (0.16862745, 0.54901961, 0.10588235), (0.16862745, 0.54901961, 0.10588235), (0.16862745, 0.54901961, 0.10588235)] fig = plt.figure(figsize=figure_size) ax = fig.add_subplot(111) ax.plot([0, 1, 1, 0], [0, -1, 1, 0], linewidth=2, color=(0.2, 0.5, 0.8)) counters = np.zeros((5, 1)) for opinion_distribution in all_opinions: classification = histogram_classification(opinion_distribution) counters[classification] += 1 ax.plot(np.absolute(opinion_distribution).mean(), opinion_distribution.mean(), 'o', linewidth=1.5, markersize=3, color=point_colors[classification]) ax.grid() plt.show() ax.set_title(figure_title, fontsize=title_font_size) ax.set_xlabel(figure_x_label, fontsize=x_label_font_size) ax.set_ylabel(figure_y_label, fontsize=y_label_font_size) print(f'number PC = {counters[0]}') print(f'number Co = {counters[1]}') print(f'number Po = {counters[2]}') print(f'number Cl = {counters[3]}') print(f'number Di = {counters[4]}')