pythonmatplotlibfigurenon-linearfigsize

Using plt.figure(figsize=()) results in multiple plots. How can I fix it?


My knowledge of python is very rudimentary, and I’m using it properly for the first for a summer project. I’m plotting the orbit diagram for a logistic map. In order to increase the size of my plot, I used plt.figure(figsize), but it resulted in more than twenty plots, none of which are what I’m looking for. Without the addition of this specific code, I’m getting my result, albeit the size of it is a little small.

As described above, I used plt.figure(figsize), and it went weird. I’ve used the same thing for another plot, and that has worked fine.

enter image description here

This is the code.

def f(x, r):
    return r*x*(1 - x);

def g(x):
    return x;

x0 = 0.8
n = np.arange(0,5000)
for r in np.linspace(3.4, 4, 200):
    xi = np.zeros(np.shape(n))
    xi[0] = x0
    for i in n:
        if i != 0:
            xi[i] = f(xi[i - 1], r)

    y = xi[1000:5000] # to ignore transient effect
    plt.figure(figsize=(5,5))
    plt.plot(r*np.ones(np.shape(y)), y, '.k', markersize=0.08)
    plt.xlabel("r")
    plt.ylabel("x")
    plt.title("Orbit Diagram - Logistic Map")


Solution

  • As already mentioned by others, the essential problem is that plt.figure() is part of your for-loop. This means: for each iteration, you create a new figure. This isn't necessary though: you can plot multiple times into the same figure, and the results will be accumulated.

    Thus, you could adjust your code by

    The following code does exactly what I described above. It produces the plot below (I manually adjusted its width after plotting):

    import numpy as np
    import matplotlib.pyplot as plt
    
    def f(x, r):
        return r*x*(1 - x)
    
    def g(x):
        return x
    
    x0 = 0.8
    n = np.arange(0,5000)
    plt.figure(figsize=(5,5))  # Only create one figure (outside loop)
    
    for r in np.linspace(3.4, 4, 200):
        xi = np.zeros(np.shape(n))
        xi[0] = x0
        for i in n:
            if i != 0:
                xi[i] = f(xi[i - 1], r)
    
        y = xi[1000:5000] # to ignore transient effect
        # Plot multiple times inside the loop
        plt.plot(r*np.ones(np.shape(y)), y, '.k', markersize=0.08)
    
    # Set labels and title only once (outside loop again)
    plt.xlabel("r")
    plt.ylabel("x")
    plt.title("Orbit Diagram - Logistic Map")
    # Actually show result. This line might or might not be necessary
    # (it wasn't necessary for me, using Spyder IDE with Qt5 backend)
    plt.show()
    

    resulting plot Is that the result that you would expect?

    By the way: I removed the semicolons ; after the return statements of your functions, as they don't do anything: In Python, the semicolon ; only serves the purpose of (1) putting what is considered multiple lines of code onto the same line and (2) suppressing outputs of the last line in Jupyter notebook cells.