Skip to content

Commit

Permalink
🆕 opinion evolution plot
Browse files Browse the repository at this point in the history
  • Loading branch information
GiulioRossetti committed Jun 22, 2019
1 parent 1be34ac commit c9099aa
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 13 deletions.
2 changes: 2 additions & 0 deletions docs/reference/models/opinion/AlgorithmicBias.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ This can be seen as a measure of the open-mindedness of individuals in a populat
It defines a threshold on the distance between the opinion of the two individuals, beyond which communication between individuals is not possible due to conflicting views.
Thus, if the distance between the opinions of the selected individuals is lower than epsilon, the two individuals adopt their average opinion. Otherwise nothing happens.

Note: setting gamma=0 reproduce the results for the Deffuant model.

--------
Statuses
--------
Expand Down
1 change: 1 addition & 0 deletions docs/reference/reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ Pyplot Viz

viz/mpl/DiffusionTrend.rst
viz/mpl/DiffusionPrevalence.rst
viz/mpl/OpinionEvolution.rst


**Model Comparison Visualizations**
Expand Down
47 changes: 47 additions & 0 deletions docs/reference/viz/mpl/OpinionEvolution.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
*****************
Opinion Evolution
*****************

The Opinion Evolution plot shows the node-wise opinion evolution in a continuous states model.

.. autoclass:: ndlib.viz.mpl.OpinionEvolution.OpinionEvolution
.. automethod:: ndlib.viz.mpl.OpinionEvolution.OpinionEvolution.__init__(model, trends)
.. automethod:: ndlib.viz.mpl.OpinionEvolution.OpinionEvolution.plot(filename)


Below is shown an example of Opinion Evolution description and visualization for the Algorithmic Bias model.

.. code-block:: python
import networkx as nx
import ndlib.models.ModelConfig as mc
import ndlib.models.opinions as op
from ndlib.viz.mpl.OpinionEvolution import OpinionEvolution
# mMean field scenario
g = nx.complete_graph(100)
# Algorithmic Bias model
model = op.AlgorithmicBiasModel(g)
# Model configuration
config = mc.Configuration()
config.add_model_parameter("epsilon", 0.32)
config.add_model_parameter("gamma", 0)
model.set_initial_status(config)
# Simulation execution
iterations = model.iteration_bunch(100)
viz = OpinionEvolution(model, iterations)
viz.plot("opinion_ev.pdf")
.. figure:: opinion_ev.png
:scale: 80 %
:align: center
:alt: Algorithmic Bias Opinion Evolution Example

SIR Diffusion Trend Example.
Binary file added docs/reference/viz/mpl/opinion_ev.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 5 additions & 4 deletions ndlib/test/test_mpl_viz.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,22 +141,23 @@ def test_trend_comparison(self):
os.remove("trend_comparison.pdf")

def test_opinion_viz(self):
g = nx.complete_graph(100)
g = nx.complete_graph(50)

model = op.AlgorithmicBiasModel(g)

# Model configuration
config = mc.Configuration()
config.add_model_parameter("epsilon", 0.32)
config.add_model_parameter("gamma", 1.2)
config.add_model_parameter("gamma", 0)
model.set_initial_status(config)

# Simulation execution
iterations = model.iteration_bunch(1000)
iterations = model.iteration_bunch(50)

viz = OpinionEvolution(model, iterations)
viz.plot("opinion_ev.pdf")
viz.plot("opinion_ev.png")
os.remove("opinion_ev.pdf")


if __name__ == '__main__':
unittest.main()
33 changes: 24 additions & 9 deletions ndlib/viz/mpl/OpinionEvolution.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from ndlib.viz.mpl.DiffusionViz import DiffusionPlot
from bokeh.palettes import Category20_9 as cols
import os
import matplotlib as mpl
if os.environ.get('DISPLAY', '') == '':
Expand All @@ -25,7 +23,7 @@ def __init__(self, model, trends):
self.srev = trends
self.ylabel = "Opinion"

def plot(self, filename=None, percentile=90):
def plot(self, filename=None):
"""
Generates the plot
Expand All @@ -44,30 +42,47 @@ def plot(self, filename=None, percentile=90):
node2col = {}

mx = 0

last_it = self.srev[-1]['iteration'] + 1
last_seen = {}

for it in self.srev:
sts = it['status']
its = it['iteration']
for n, v in sts.items():
if n in nodes2opinions:
nodes2opinions[n].append(v)
last_id = last_seen[n]
last_value = nodes2opinions[n][last_id]

for i in range(last_id, its):
nodes2opinions[n][i] = last_value

nodes2opinions[n][its] = v
last_seen[n] = its
else:
nodes2opinions[n] = [v]
nodes2opinions[n] = [0]*last_it
nodes2opinions[n][its] = v
last_seen[n] = 0
if v < 0.33:
node2col[n] = '#ff0000'
elif 0.33 <= v <= 0.66:
node2col[n] = '#00ff00'
else:
node2col[n] = '#0000ff'

mx = 0
for k, l in future.utils.iteritems(nodes2opinions):
mx = len(l)
plt.plot(range(0, mx), l, lw=1, alpha=0.5, color=node2col[k])
if mx < last_seen[k]:
mx = last_seen[k]
x = list(range(0, last_seen[k]))
y = l[0:last_seen[k]]
plt.plot(x, y, lw=1, alpha=0.5, color=node2col[k])

# plt.grid(axis="y")
plt.title(descr)
plt.xlabel("Iterations", fontsize=24)
plt.ylabel(self.ylabel, fontsize=24)
plt.legend(loc="best", fontsize=18)
plt.xlim((0, mx))


plt.tight_layout()
if filename is not None:
Expand Down

0 comments on commit c9099aa

Please sign in to comment.