matplotlib autoscale(axis='y') after slicing plot with set_xlim()

前端 未结 1 545
没有蜡笔的小新
没有蜡笔的小新 2021-01-25 11:37

As a demonstration, I\'m plotting x^0 through x^9 with x values in range from 10 to 20.

Then I\'m slicing those images so that I have 9 slices:

x = (10 to 11), (

相关标签:
1条回答
  • 2021-01-25 11:47

    I solved my issue last night by creating a dictionary with x's as keys and a respective list of y's as values.

    This occurs as the data is created by the function y=x**i

    in essence I'm creating dictionary structure pseudocode:

    data[x0] = [x0y1,x0y2,x0y3....]
    data[x1] = [x1y1,x1y2,x1y3....]
    data[x2] = [x2y1,x2y2,x2y3....]
    etc.
    

    I can later reference all the y values at any given x. From there, find the min and max y value for the left and right side of my slice to manually set ylim. If your xlim slice was more than one x segment wide you'd have to repeat the process for each respective x slice within your xlim. In my instance, my x slices are exactly one segment wide.

    import matplotlib.pyplot as plt
    import numpy as np
    
    # move my range function out of my data creation loop
    x = np.arange(10,20,1)
    
    # create a dictionary of my data with x values as keys
    data = {}
    for i in range(len(x)):
       data[x[i]]=[]
    
    # create some test data
    for i in range(10):
        y = x**i
        plt.plot(x,y,c='red',marker='.',ms=2)
    
        # store my y data to my data dictionary as its created
        xx = x[-len(y):]
        for j in range(len(xx)):
            data[xx[j]].append(y[j])
    
    # get all x values in chart and reduce to a sorted list set
    xd = [] 
    for n in range(len(plt.gca().get_lines())):
            line = plt.gca().get_lines()[n]
            xd.append((line.get_xdata()).tolist())
    xd = [item for sublist in xd for item in sublist]
    xd = sorted(list(set(xd)))
    
    # attempt to plot slices of x with autoscaled y
    ax = plt.gca()
    for i in range(len(xd)-1):
        ax.set_xlim([xd[i],xd[i+1]])
    
        # reference my min and max y values by left and right borders of x slice
        ymin = min(min(data[xd[i]]), min(data[xd[i+1]]))
        ymax = max(max(data[xd[i]]), max(data[xd[i+1]]))
        # manually set y limits
        ax.set_ylim([ymin,ymax])
    
        #eliminate my autoscale call
        #ax.axes.autoscale(enable=True,axis='y', tight=True)
        plt.pause(1) #timing
    

    Now when it plots, y is autoscaled to the x slice, not the entire dataset.

    0 讨论(0)
提交回复
热议问题