Home > Software engineering >  Plotting random graphs in Python
Plotting random graphs in Python

Time:05-30

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()

CodePudding user response:

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

CodePudding user response:

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 )

  • Related