How to extract data from matplotlib plot
Question:
I have a wxPython
program which reads from different datasets, performs various types of simple on-the-fly analysis on the data and plots various combinations of the datasets to matplotlib
canvas. I would like to have the opportunity to dump currently plotted data to file for more sophisticated analysis later on.
The question is: are there any methods in matplotlib
that allow access to the data currently plotted in matplotlib.Figure
?
Answers:
Its Python, so you can modify the source script directly so the data is dumped before it is plotted
Jakub is right about modifying the Python script to write out the data directly from the source from which it was sent into the plot; that’s the way I’d prefer to do this. But for reference, if you do need to get data out of a plot, I think this should do it
gca().get_lines()[n].get_xydata()
Alternatively you can get the x and y data sets separately:
line = gca().get_lines()[n]
xd = line.get_xdata()
yd = line.get_ydata()
The matplotlib.pyplot.gca
can be used to extract data from matplotlib plots. Here is a simple example:
import matplotlib.pyplot as plt
plt.plot([1,2,3],[4,5,6])
ax = plt.gca()
line = ax.lines[0]
line.get_xydata()
On running this, you will see 2 outputs – the plot and the data:
array([[1., 4.],
[2., 5.],
[3., 6.]])
You can also get the x data and y data seperately.
On running line.get_xdata()
, you will get:
array([1, 2, 3])
And on running line.get_ydata()
, you will get:
array([4, 5, 6])
Note: gca
stands for get current axis
I know this is an old question, but I feel there is a solution better than the ones offered here so I decided to write this answer.
You can use unittest.mock.patch
to temporarily replace the matplotlib.axes.Axes.plot
function:
from unittest.mock import patch
def save_data(self, *args, **kwargs):
# save the data that was passed into the plot function
print(args)
with patch('matplotlib.axes.Axes.plot', new=save_data):
# some code that will eventually plot data
a_function_that_plots()
Once you exit the with
block, Axes.plot
will resume normal behavior.
To sum up, for future reference:
If plotting with plt.plot()
or plt.stem()
or plt.step()
you can get a list of Line2D objects with:
ax = plt.gca() # to get the axis
ax.get_lines()
For plt.pie()
, plt.bar()
or plt.barh()
you can get a list of wedge or rectangle objects with:
ax = plt.gca() # to get the axis
ax.patches()
Then, depending on the situation you can get the data by running get_xdata()
, get_ydata()
(see Line2D) for more info.
or i.e get_height()
for a bar plot (see Rectangle) for more info.
In general for all basic plotting functions, you can find what you are looking for by running ax.get_children()
that returns a list of the children Artists
(the base class the includes all of the figure’s elements).
As pointed out in the answer by @mobiuscreek, the way to extract data from axis depends on the function used for plotting: e.g., ax.get_lines()
would work for a plot created via ax.plot()
, but it gives an empty array, if the lines were created, e.g., using matplotlib.collections.LineCollection
. (It is likely to be more of a problem when the figures are created by a third-party code.)
The general approach is then using ax.get_children()
and parsing it as needed. See, e.g., this answer.
I have a wxPython
program which reads from different datasets, performs various types of simple on-the-fly analysis on the data and plots various combinations of the datasets to matplotlib
canvas. I would like to have the opportunity to dump currently plotted data to file for more sophisticated analysis later on.
The question is: are there any methods in matplotlib
that allow access to the data currently plotted in matplotlib.Figure
?
Its Python, so you can modify the source script directly so the data is dumped before it is plotted
Jakub is right about modifying the Python script to write out the data directly from the source from which it was sent into the plot; that’s the way I’d prefer to do this. But for reference, if you do need to get data out of a plot, I think this should do it
gca().get_lines()[n].get_xydata()
Alternatively you can get the x and y data sets separately:
line = gca().get_lines()[n]
xd = line.get_xdata()
yd = line.get_ydata()
The matplotlib.pyplot.gca
can be used to extract data from matplotlib plots. Here is a simple example:
import matplotlib.pyplot as plt
plt.plot([1,2,3],[4,5,6])
ax = plt.gca()
line = ax.lines[0]
line.get_xydata()
On running this, you will see 2 outputs – the plot and the data:
array([[1., 4.],
[2., 5.],
[3., 6.]])
You can also get the x data and y data seperately.
On running line.get_xdata()
, you will get:
array([1, 2, 3])
And on running line.get_ydata()
, you will get:
array([4, 5, 6])
Note: gca
stands for get current axis
I know this is an old question, but I feel there is a solution better than the ones offered here so I decided to write this answer.
You can use unittest.mock.patch
to temporarily replace the matplotlib.axes.Axes.plot
function:
from unittest.mock import patch
def save_data(self, *args, **kwargs):
# save the data that was passed into the plot function
print(args)
with patch('matplotlib.axes.Axes.plot', new=save_data):
# some code that will eventually plot data
a_function_that_plots()
Once you exit the with
block, Axes.plot
will resume normal behavior.
To sum up, for future reference:
If plotting with plt.plot()
or plt.stem()
or plt.step()
you can get a list of Line2D objects with:
ax = plt.gca() # to get the axis
ax.get_lines()
For plt.pie()
, plt.bar()
or plt.barh()
you can get a list of wedge or rectangle objects with:
ax = plt.gca() # to get the axis
ax.patches()
Then, depending on the situation you can get the data by running get_xdata()
, get_ydata()
(see Line2D) for more info.
or i.e get_height()
for a bar plot (see Rectangle) for more info.
In general for all basic plotting functions, you can find what you are looking for by running ax.get_children()
that returns a list of the children Artists
(the base class the includes all of the figure’s elements).
As pointed out in the answer by @mobiuscreek, the way to extract data from axis depends on the function used for plotting: e.g., ax.get_lines()
would work for a plot created via ax.plot()
, but it gives an empty array, if the lines were created, e.g., using matplotlib.collections.LineCollection
. (It is likely to be more of a problem when the figures are created by a third-party code.)
The general approach is then using ax.get_children()
and parsing it as needed. See, e.g., this answer.