0

I'm trying to add a second x-axis to the plot generated by the script below. The plot is continuously being updated:

import numpy as np
import matplotlib.pyplot as plt


#turn interactive mode on
plt.ion()

def GetTestData():
    data = []
    for i in range(0, 2048):
        data.append(np.random.random_sample() * i)
    return data

for i in range(0, 100):
    plt.clf()
    plt.plot(GetTestData())
    plt.show()
    plt.pause(0.05)

I found this Stack Overflow solution on how to add an extra axis, but when I tried using the solution in my script, I get many plots instead of refreshing a single one:

import numpy as np
import matplotlib.pyplot as plt


#turn interactive mode on
plt.ion()

def GetTestData():
    data = []
    for i in range(0, 2048):
        data.append(np.random.random_sample() * i)
    return data

for i in range(0, 100):
    plt.clf()

    fig = plt.figure()
    ax1 = fig.add_subplot(111)
    ax2 = ax1.twiny()

    ax1.plot(GetTestData())

    ax2.plot(range(100), np.ones(100)) # Create a dummy plot
    ax2.cla()

    plt.show()
    plt.pause(0.05)

Any help would be appreciated

Q-bertsuit
  • 3,223
  • 6
  • 30
  • 55
  • A very small trial: figure creation and `ax2 = ax1.twiny()` outside the loop? – Uvar Feb 15 '18 at 13:24
  • You create a new figure and new subplots within the loop. If that is not desired, put this outside the loop. – ImportanceOfBeingErnest Feb 15 '18 at 13:25
  • @Uvar Moving those 3 lines outside of the loop results in a blank plot – Q-bertsuit Feb 15 '18 at 13:30
  • Nothing weird there. :) `plt.clf()` does what it is intended to do, it clears the plot. Similarly, `plt.figure()` does what it is supposed to do: open a figure. You want all the drawings in one plot. Added an ugly solution. Feel free to improve it to re-use axes definition instead of re-defining them inside the loop every iteration. – Uvar Feb 15 '18 at 13:50

2 Answers2

0

I think you need to put an hold somwere there:

...
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax2 = ax1.twiny()

ax1.plot(GetTestData())
hold(True)
ax2.plot(range(100), np.ones(100)) # Create a dummy plot
ax2.cla()
Petronella
  • 2,327
  • 1
  • 15
  • 24
0

So the final solution I came up with is to only update the y_data of the same axes object within the loop..

import numpy as np
import matplotlib.pyplot as plt


#turn interactive mode on
plt.ion()

def GetTestData():
    data = []
    for i in range(0, 2048):
        data.append(np.random.random_sample() * i)
    return data
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax2 = ax1.twiny()
line1, = ax1.plot(GetTestData())
line2, = ax2.plot(range(100), np.ones(100))
for i in range(0, 100):
    line1.set_ydata(GetTestData())
    #line2.set_ydata(range(100), np.ones(100))
    plt.pause(0.05)
    fig.canvas.draw()
Uvar
  • 3,372
  • 12
  • 25
  • A downvote, in spite of me claiming the solution to be sub-optimal AND it doing what OP seems to request: a time-evolving plot. If downvoting, then please also comment on what is unsatisfactory :) – Uvar Feb 15 '18 at 13:45
  • Suboptimal solution can be downvoted because they are not useful. If you know already that the solution is suboptimal and you even know the reason, namely clearing the figure, why not provide an optimal solution instead? – ImportanceOfBeingErnest Feb 15 '18 at 13:53
  • The suboptimal one can still be used if performance is really not the bottleneck. ~~ Depends on what is the use case. (and me running into the standard `hold(on)` mode of matplotlib prevents me from posting a better solution for now.. – Uvar Feb 15 '18 at 13:56
  • Precisely. So if people browse through several answers here and see a low vote they know that they might not want to use this solution. So will you update the answer or should I provide an optimal solution? – ImportanceOfBeingErnest Feb 15 '18 at 13:59
  • Released a new one. Anyway, I think our ideology differs. ;) ~ I will upvote an answer I think is worth upvoting. But downvotes are reserved for wrong answers. That way, the division is still made, but people investing time to come up with a working solution are not punished for doing so. By posting suboptimal ones, the rewards will be significantly lower. That is only normal – Uvar Feb 15 '18 at 14:05