JackEight
JackEight

Reputation: 113

Plotting random graphs in Python

I am interested in plotting a random graph in Python.

More precisely, I consider all the points (x, y) with integer coordinates, such that |x| < 30, |y| < 30 (n = 30 is just an example here).

Then, for each couple of points, I decide with probability p (we can say p = 0.5) whether these two points are connected or not.

Then, I want to plot all the segments I got. For instance, we could get something like that:

Random graph

The problem I encounter is that plotting all these segments takes quite some time. And of course, it increases with both n and p.

So my question is: how can I plot quickly all these segments using pyplot ?

Thank you for your help.

EDIT: here is an example of a code that works, but that is slow.

import numpy as np
import matplotlib.pyplot as plt

for i in range(101):
    for j in range(101):
        if i < 100:
            if np.random.uniform() < 1/2:
                plt.plot([i - 50, i - 50 + 1], [j - 50, j - 50], "r")
        if j < 100:
            if np.random.uniform() < 1/2:
                plt.plot([i - 50, i - 50], [j - 50, j - 50 + 1], "r")
                
plt.show()

Upvotes: 1

Views: 780

Answers (2)

ravenspoint
ravenspoint

Reputation: 20462

It looks to me like your "segments" are actually single pixels.

plt.plot([i - 50, i - 50 + 1], [j - 50, j - 50], "r")

is a horribly inefficient way to set the color of a pixel.

Suggest: Create a matrix in memory, and calculate the locations that need to be colored. Then iterate through the matrix, and for each location that is set, color the corresponding pixel. If you have a decent graphics library then if you postpone the screen update until all the pixel are colored, then you will get a huge perfomance boost. ( Using the windows API you can use a "memory device context" and when finished swap the entire context from memory to the screen )

Upvotes: 1

Ultramoi
Ultramoi

Reputation: 213

You have not provided a source code, but I guess that you are generating your segments, and then plot them separately using plt.plot(point_A, point_B)

You should consider one of the following solutions:

1. Plot your graph as a 2D image

Instead of considering your graph as a list of segments, we consider it as a 2d matrix of connections, and simply plot that matrix once.

E.g.


segments = ... # you generate this list of pairs (POINT_A, POINT_B) that define your segments using your algorithm

matrix = np.zeros((30, 30))
for ((xA, yA), (xB, yB)) in segments:
   # we re-order coordinates in order to always have A inferior to B
   if yA > yB:
      yA, yB = yB, yA
   if xA > xB:
      xA, xB = xB, xA

   # we mark all points belonging to the segment [A, B] as True in the matrix
   matrix[yA:yB+1, xA:xB+1] = 1
plt.imshow(matrix)

I have not tested the code and provide it just to illustrate the idea.

2. Use lineCollections from matplotlib

Best described here: https://stackoverflow.com/a/21357666/5728381

Upvotes: 2

Related Questions