dafeda
dafeda

Reputation: 1317

Scatter plot in matplotlib not updating xlim and ylim

Given the below code I would expect the x-axis to be between 0 and 3 with some margins added. Instead it is much larger. I would expect the call to scatter to automatically update x-axis limits. I could set the xlim and ylim my self but would like them to be set automatically. What am I doing wrong?

import matplotlib.pyplot as plt

if __name__ == '__main__':

    fig = plt.figure()
    ax = fig.add_subplot(111)

    x = [0, 4000, 8000, 100000]
    y = [0, 10, 100, 150]
    ax.scatter(x, y)

    x = [0, 1, 2, 3]
    y = x

    ax.clear()

    ax.scatter(x, y)
    plt.show()

enter image description here

Upvotes: 2

Views: 2808

Answers (4)

dafeda
dafeda

Reputation: 1317

Here is a way of making another scatter plot without needing to clear the figure. I basically update offests of PathCollection returned by axes.scatter() and add the collection back to the axes. Of course, the axes has to be cleared first. One thing I notice is that I have to manually set the margins.

import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure()
ax = fig.add_subplot(111)

x = [0, 4000, 8000, 100000]
y = [0, 10, 100, 150]
scat = ax.scatter(x, y)

x = [0, 1, 2, 3]
y = x

ax.clear()
corners = (min(x), min(y)), (max(x), max(y))
ax.update_datalim(corners)
ax.margins(0.05, 0.05)
ax.autoscale_view()
scat.set_offsets(np.vstack((x,y)).transpose())
ax.add_collection(scat)

plt.show()

Upvotes: 1

You can clear the figure, and open a new subplot, than the axes will be adjusted as you wanted.

fig = plt.figure()
ax = fig.add_subplot(111)

x = [0, 4000, 8000, 100000]
y = [0, 10, 100, 150]
ax.scatter(x, y)

plt.clf()
ax = fig.add_subplot(111)

x = [0, 1, 2, 3]
y = x

ax.scatter(x, y)
plt.show()

Edit: In this version figure is not closed, just cleared with the clf function.

Upvotes: 2

tacaswell
tacaswell

Reputation: 87366

It is a feature that scatter does not automatically re-limit the graph as in many cases that would be undesirable. See Axes.autoscale and Axes.relim

ax.relim()  # might not be needed 
ax.autoscale()

should do what you want.

Upvotes: 2

Sleepyhead
Sleepyhead

Reputation: 1021

If you comment out the first scatter, everything will be fine

Upvotes: 0

Related Questions