# How do I extract data from MATLAB figures?

5,455 views (last 30 days)

Show older comments

### Accepted Answer

MathWorks Support Team
on 11 Nov 2020

Edited: MathWorks Support Team
on 28 Mar 2022

This example shows how to extract data from a MATLAB figure.

If the figure is stored in a file, such as 'example.fig', then open the figure file using 'openfig'. Assign the Figure object to the variable 'fig'.

fig = openfig('example.fig');

If the figure is already open, then use 'gcf' to access the Figure object and assign it to the variable 'fig'.

fig = gcf;

There are several ways to access the data for the plotted graphics objects. You can use the Children property or you can use 'findobj'.

Use Children Property

Access the plotted graphics objects through the Children properties. The Axes objects are children of the figure. The plotted graphics objects are typically children of the Axes object.

axObjs = fig.Children

dataObjs = axObjs.Children

The 'dataObjs' array that appears in the Command Window indicates the types of graphics objects in the axes. Different graphics objects store data differently. For example, Line objects store the data in the 'XData', 'YData', and 'ZData' properties. If the first element in 'dataObjs' is a Line object, then access its data using this code.

x = dataObjs(1).XData

y = dataObjs(1).YData

z = dataObjs(1).ZData

If the figure contains other types of graphics objects, then use the appropriate properties to access the data. For a list of graphics objects and their properties, see:

Use findobj Function

Alternatively, you can find all the graphics objects in a figure with a certain data property. For example, find all graphics objects that have a 'YData' property. Then access the 'YData' values for the first object.

dataObjs = findobj(fig,'-property','YData')

y1 = dataObjs(1).YData

##### 8 Comments

Ren Li
on 8 Sep 2021

clear all;

close all;

clc;

fig=openfig('xxxxx.fig');

dataObjsY = findobj(fig,'-property','YData');

y1 = dataObjsY(1).YData;

y2 = dataObjsY(2).YData;

dataObjsX = findobj(fig,'-property','XData');

x1 = dataObjsX(1).XData;

x2 = dataObjsX(2).XData;

A=[];

A(:,1)=x1;

A(:,2)=y1;

A(:,3)=x2;

A(:,4)=y2;

dlmwrite('xxxxx.txt',A,',');

### More Answers (8)

Felipe Bittencourt de Souza
on 15 Dec 2017

I was having the same error message mentioned before: "Error using get Conversion to double from cell is not possible."

I solved this issue with Walter Roberson's answer, using the following code:

open('example.fig');

a = get(gca,'Children');

xdata = get(a, 'XData');

ydata = get(a, 'YData');

zdata = get(a, 'ZData');

Yair Altman
on 21 May 2018

Edited: MathWorks Support Team
on 19 Apr 2021

Note that the official MathWorks answer above relies on opening and displaying the figure (using the open() function) before extracting its contents. This is both slow and potentially unwanted (we don't always want to display the figures), especially if we're looping over many FIG files.

Instead, users can directly read and analyze the *.fig file by loading it into Matlab memory using the load() function, since *.fig files are basically simple MAT files with a .fig (rather than .mat) file extension.

Fortunately, the internal format of these files has changed very little over the years - a few fields have changed their name, but the basic file data structure remained the same. So essentially the same code can be used to extract data from .fig files created a decade ago, as well as the latest Matlab release.

Note that the fact that FIG files are basically just MAT files is an undocumented feature of Matlab, and so it might change one day. But for now it is a very handy feature to use.

##### 4 Comments

Walter Roberson
on 22 Apr 2022 at 1:51

[filename, filepath] = uigetfile('*.fig');

if ~ischar(filename)

error('cancel');

end

fullname = fullfile(filepath, filename);

fig = openfig(fullname);

all_ax = findobj(fig, 'type', 'axes');

all_titles = cellfun(@(T) T.String, get(all_ax, 'title'), 'uniform', 0);

all_lines = arrayfun(@(A) findobj(A, 'type', 'line'), all_ax, 'uniform', 0);

all_XData = cellfun(@(L) get(L,'XData'), all_lines, 'uniform', 0);

all_YData = cellfun(@(L) get(L,'YData'), all_lines, 'uniform', 0);

for axIdx = 1 : numel(all_YData)

if iscell(all_YData{axIdx})

mask = cellfun(@(Y) ~isequal(Y, [0 0]), all_YData{axIdx});

all_XData{axIdx} = all_XData{axIdx}(mask);

all_YData{axIdx} = all_YData{axIdx}(mask);

else

all_XData{axIdx} = {all_XData{axIdx}};

all_YData{axIdx} = {all_YData{axIdx}};

end

end

This code permits you to select a .fig file, and processes it. It outputs a cell array of character vectors named all_titles . It outputs a cell array named all_XData in which there is one celll array entry for each axes, that contains an entry for each line inside the axes, that is the line x coordinates. It outputs a cell array named all_YData in which there is one celll array entry for each axes, that contains an entry for each line inside the axes, that is the line y coordinates. The coordinate entries have been filtered to remove any lines with Y coordinate [0 0]

The difference between this code and the previous version is that this version filters out lines where the y coordinate is just [0 0]. This version also accounts for the possibility that an axes only has one line.

In the case where the axes had more than one line, the internal get() call would have returned a cell array of coordinates, but in the case where the axes had exactly one line, the internal get() call would have returned the numeric coordinates directly: this code detects the single-line case and deliberately wraps it inside a cell array, so that the outputs are consistent.

So, for axes #K,all_titles{K} is a character vector that is the axes title, and all_XData{K} is a cell array with one entry per line inside the axes for the X coordinates, and all_YData{K} is a cell array with one entry per line inside the axes for the Y coordinates.

This code does not assume that all of the lines inside an axes have the same number of points. If you are willing to assume that, then you can process the arrays further by

XData_matrices = cellfun(@cell2mat, all_XData);

YData_matrices = cellfun(@cell2mat, all_YData);

and then those would be cell arrays with one entry per axes, and the entries would be N x L numeric arrays where N is the number of lines and L is the number of points in the line.

Michael
on 13 Jun 2014

Edited: Michael
on 13 Jun 2014

I tried to follow these steps, but when I got to objTypes = get(dataObjs, 'Type') I got this error:

Error using get Conversion to double from cell is not possible.

I don't know Matlab's figure format and I'm not familiar with Matlab's API for accessing figure data. I'm not sure what this error means.

If anyone else happens upon this: Matlab figures are just ".mat" files. The scipy.io library in Pylab can read Matfiles into numpy structures using the 'loadmat' command. One can then browse the figure data in Python and locate the data.

Edit: one can also step through the figure data in Matlab, by loading the figure using the command "s=load('Figure.fig','-mat')". The solutions using "get" never really worked for me. I think this is because every figure is structured slightly differently, and people are posting solutions that work for a particular figure, but don't generalize well. If you just grab the figure data structure, you can step through it and find what you need.

##### 3 Comments

Walter Roberson
on 12 Nov 2016

Julia Mödl : you would have that problem if the axes you were looking at was a placeholder rather than an axes object.

all_axesObjs = findobj(h, 'type', 'axes');

now only examine the items in all_axesObjs.

Or use what I posted earlier,

lineObjs = findobj(dataObjs, 'type', 'line');

xdata = get(lineObjs, 'XData');

ydata = get(lineObjs, 'YData');

Yun-Han Lee
on 27 Mar 2020

A simple workaround with a bit sacrifice in precision (pretty manual though):

- Open a figure, and then Tools>Basic Fitting.

2. Choose 'shape perserving interpolant,' then hit the arrow at the buttom twice to expand to the full panel.

3. Enter x of interest, then Evaluate, and then Save to workspace.

Parrish.Ch
on 23 Jul 2015

Hi all,

I noticed people were having issues with getting the following error when attempting to run:

objsTypes = get(dataObjs,'Types')

Error using get Conversion to double from cell is not possible.

I think I have a solution to the issue. For surface plots, I noticed that the children of an axes object (so dataObjs in this case) may contain a subgroup that is a complex cell. You have to use cell2struct to break this cell into it's basic pieces so you can extract the data. Here is the code for my solution:

h = gcf;

axes = get(h,'Children');

dataObjs = get(axes,'Children');

Props = cell2struct(dataObjs,'SurfaceProps',2);

SurfaceData = Props.SurfaceProp;

XData = SurfaceData(3,1).XData;

YData = SurfaceData(3,1).YData;

ZData = SurfaceData(2,1).ZData;

**Before you just copy paste this code, there are a few important things to know.

My variable dataObjs is a 2x1 cell. The first index in the cell is empty but the second index is a 3x1 Group. I have to convert this cell group to a structure that can then be used to access my data. From there, I use cell2struct on the second index to accomplish this. The cell2struct generates a property that is named in the second argument of the cell2struct command ('SurfaceProp' for me). Props.SurfaceProp extracts the various "children" from the 3x1 Group in dataObjs. In my case, I have three objects in Props.SurfaceProp: two light objects and one surface object. The surface object contains the x, y, and z data. My surface object is the third index in the matrix generated by Props.SurfaceProp, so I use SurfaceData(3,1).XData to access the XData handle that is in the third index of the SurfaceData array.

I hope this helps!

##### 2 Comments

Walter Roberson
on 12 Nov 2016

Chetanya
on 10 Nov 2019

I wrote a small function to extract data from file following the MATHWORKS staff answer. Here it goes, https://www.mathworks.com/matlabcentral/fileexchange/73274-extract_data_from_figures?s_tid=prof_contriblnk

Please feel free to suggest if you find any bugs.

##### 0 Comments

Abhishek Shahi
on 23 Apr 2020

Edited: Abhishek Shahi
on 23 Apr 2020

I hope this will help

x = get (gco, 'XData');

y = get(gco, 'YData');

z = get(gco, 'CData') ;

##### 2 Comments

Shreeyesh Biswal
on 9 Jul 2021

Daniel Ares
on 19 Jun 2017

Edited: Walter Roberson
on 27 Mar 2020

Hi to everybody,

i can´t run it, i get this error, with this code.

open('Force vs Time.fig');

h = gcf; %current figure handle

axesObjs = get(h, 'Children'); %axes handles

dataObjs = get(axesObjs, 'Children'); %handles to low-level graphics objects in axes

lineObjs = get(dataObjs, 'type', 'line'); %type of low-level graphics object

xdata = get(lineObjs, 'XData'); %data from low-level grahics objects

ydata = get(dataObjs, 'YData');

zdata = get(dataObjs, 'ZData');

Thanks

##### 1 Comment

Jan
on 19 Jun 2017

You forgot to mention the error you get. But please remove this message and post it as a new question, because this is the section for answers. Thanks.

You will get an answer like:

lineObjs = get(dataObjs, 'type', 'line')

get() does not accept 3 inputs. Do you mean:

lineObjs = findobj(dataObjs, 'type', 'line')

? Note: Please delete this message even if this solves your problem.

### See Also

### Products

### Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!