Search code examples
pythonmatplotlibgraph

Extract (x,y) values from a line graph


Suppose I have 2 sets of data and I use plt.plot to plot the graph.

import matplotlib.pyplot as plt
import numpy as np

x=range(5,46,5)
y=[1.60,1.56,1.54,1.53,1.53,1.58,1.70,1.97,2.68]


plt.plot(x,y)

How can I get the x,y values of the line graph created by plt.plot?

Edit for clarity: What I want to do is getting the coordinates of the line that is created by plt.plot, not getting the data that is used to create the graph.

Edit for even more clarity: I want to get the coordinates of the points in between each of my (x,y) pairs in the line plotted by pyplot.


Solution

  • An Axes object has a property transData. This transformation can be used to translate data coordinates into display coordinates:

    x=range(5,46,5)
    y=[1.60,1.56,1.54,1.53,1.53,1.58,1.70,1.97,2.68]
    
    plt.gca().set_xlim(5,46)
    plt.gca().set_ylim(1.5,3)
    plt.plot(x,y)
    
    print(plt.gca().transData.transform(list(zip(x,y))))
    

    The last line prints the array of data points expressed in display coordinates:

    [[ 54.          50.496     ]
     [ 94.82926829  44.6976    ]
     [135.65853659  41.7984    ]
     [176.48780488  40.3488    ]
     [217.31707317  40.3488    ]
     [258.14634146  47.5968    ]
     [298.97560976  64.992     ]
     [339.80487805 104.1312    ]
     [380.63414634 207.0528    ]]
    

    This output means that the first datapoint (5, 1.60) is displayed at (54.0, 50.495) and the last datapoint (45, 2.69) is displayed at (380.634, 207.052).

    Edit: The remaining points between two datapoints from this list can be calculated using interp1d:

    display_coords = plt.gca().transData.transform(list(zip(x,y)))
    from scipy.interpolate import interp1d
    f = interp1d(display_coords[:,0], display_coords[:,1])
    display_x = np.linspace(min(display_coords[:,0]), max(display_coords[:,0]), num=100, endpoint=True)
    list(zip(display_x, f(display_x)))
    

    Result:

    [(54.0, 50.49599999999998),
     (57.29933481152993, 50.0274424242424),
     (60.59866962305987, 49.55888484848483),
     (63.8980044345898, 49.09032727272725),
     (67.19733924611974, 48.62176969696967),
    ...
     (367.43680709534374, 173.78521212121217),
     (370.7361419068736, 182.102109090909),
     (374.0354767184036, 190.41900606060602),
     (377.3348115299335, 198.735903030303),
     (380.63414634146346, 207.0528)]
    

    The actual values depend on the display, settings etc and might vary.