2

I'm trying to go away from matlab and use python + matplotlib instead. However, I haven't really figured out what the matplotlib equivalent of matlab 'handles' is. So here's some matlab code where I return the handles so that I can change certain properties. What is the exact equivalent of this code using matplotlib? I very often use the 'Tag' property of handles in matlab and use 'findobj' with it. Can this be done with matplotlib as well?

% create figure and return figure handle
h = figure();
% add a plot and tag it so we can find the handle later
plot(1:10, 1:10, 'Tag', 'dummy')
% add a legend
my_legend = legend('a line')
% change figure name
set(h, 'name', 'myfigure')
% find current axes
my_axis = gca();
% change xlimits
set(my_axis, 'XLim', [0 5])
% find the plot object generated above and modify YData
set(findobj('Tag', 'dummy'), 'YData', repmat(10, 1, 10))

3 Answers 3

4

There is a findobj method is matplotlib too:

import matplotlib.pyplot as plt
import numpy as np

h = plt.figure()
plt.plot(range(1,11), range(1,11), gid='dummy')
my_legend = plt.legend(['a line'])
plt.title('myfigure')  # not sure if this is the same as set(h, 'name', 'myfigure')
my_axis = plt.gca()
my_axis.set_xlim(0,5)
for p in set(h.findobj(lambda x: x.get_gid()=='dummy')):
    p.set_ydata(np.ones(10)*10.0)
plt.show()

Note that the gid parameter in plt.plot is usually used by matplotlib (only) when the backend is set to 'svg'. It use the gid as the id attribute to some grouping elements (like line2d, patch, text).

Sign up to request clarification or add additional context in comments.

4 Comments

great! so is the 'gid' property in matplotlib similar to the 'Tag' property in matlab, i.e, does it exist for any kind of object (figure, plot, legend).
No, plt.figure and plt.legend do not accept the gid parameter. If you need to keep track of groups of objects in general, it might be easier to use a dict which maps from tag names like 'dummy' to lists of objects. Then you don't need rely on matplotlib's findobj either.
but in that case I need to always store the list of objects somewhere. That's the beauty of findobj - I can find objects that don't be long together and I don't need to explicitly save those object (and pass them on).
findobj in matplotlib also works recursively and you can select objects based on any set of properties, existence of attributes, container/containment relations and class. So it has the same powers as that in matlab. The artist tutorial shows a huge range of properties you can set and much more: matplotlib.sourceforge.net/api/artist_api.html. Read the docs and cookbooks- there is a huge amount of power and flexibility there.
0

I have not used matlab but I think this is what you want

import matplotlib
import matplotlib.pyplot as plt

x = [1,3,4,5,6]
y = [1,9,16,25,36]
fig = plt.figure()
ax = fig.add_subplot(111)  # add a plot
ax.set_title('y = x^2')
line1, = ax.plot(x, y, 'o-')       #x1,y1 are lists(equal size)
line1.set_ydata(y2)                #Use this to modify Ydata
plt.show()

Of course, this is just a basic plot, there is more to it.Go though this to find the graph you want and view its source code.

2 Comments

you don't modify the YData once you've plotted them. If a 'findobj' equivalent doesn't exist in matplotlib, then I'd like to see how to do this differently. Thanks!
just an addition: if you want to update ydata dynamically (as in interactive mode or for animation), you have to refresh the figure after set_ydata() by calling the draw() function.
0
# create figure and return figure handle
h = figure()

# add a plot but tagging like matlab is not available here. But you can
# set one of the attributes to find it later. url seems harmless to modify.
# plot() returns a list of Line2D instances which you can store in a variable  
p = plot(arange(1,11), arange(1,11), url='my_tag')

# add a legend
my_legend = legend(p,('a line',)) 
# you could also do 
# p = plot(arange(1,11), arange(1,11), label='a line', url='my_tag')
# legend()
# or
# p[0].set_label('a line')
# legend()

# change figure name: not sure what this is for.
# set(h, 'name', 'myfigure') 

# find current axes
my_axis = gca()
# change xlimits
my_axis.set_xlim(0, 5)
# You could compress the above two lines of code into:
# xlim(start, end)

# find the plot object generated above and modify YData
# findobj in matplotlib needs you to write a boolean function to 
# match selection criteria. 
# Here we use a lambda function to return only Line2D objects 
# with the url property set to 'my_tag'
q = h.findobj(lambda x: isinstance(x, Line2D) and x.get_url() == 'my_tag')

# findobj returns duplicate objects in the list. We can take the first entry.
q[0].set_ydata(ones(10)*10.0) 

# now refresh the figure
draw()

3 Comments

if you install ipython, which has special matplotlib support, you can use it interactively like matlab(with tab-key-autocompletion). run: ipython -pylab
if matlab like tagging is not available, can I tag (and find) objects differently?
yeah, I just updated the answer. and here you can have as much complexity in your search criteria(way beyond tagging) as you want.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.