12

I have a follow up question to this question.

Is it possible to streamline the figure generation by having multiple python scripts that work on different parts of the figure?

For example, if I have the following functions:

FunctionA: Draw a histogram of something
FunctionB: Draw a box with a text in it
FunctionC: Draw a plot of something C
FunctionD: Draw a plot of something D

How do I go about reusing the above functions in different scripts? If I wanted, for instance, to create a figure with a histogram with a plot of something C, I would somehow call FunctionA and FunctionC from my script. Or, if I wanted a figure with the two plots, I'd call FunctionC and FunctionD.

I'm not sure if I'm explaining myself clearly, but another way of asking this question is this: how do I pass a figure object to a function and then have the function draw something to the passed figure object and then return it back to the main script to add other things like the title or something?

2 Answers 2

8

Here you want to use the Artist objects, and pass them as needed to the functions:

import numpy as np
import matplotlib.pyplot as plt

def myhist(ax, color):
    ax.hist(np.log(np.arange(1, 10, .1)), facecolor=color)

def say_something(ax, words):
    t = ax.text(.2, 20., words)
    make_a_dim_yellow_bbox(t)

def make_a_dim_yellow_bbox(txt):
    txt.set_bbox(dict(facecolor='yellow', alpha=.2))

fig = plt.figure()
ax0 = fig.add_subplot(1,2,1)
ax1 = fig.add_subplot(1,2,2)

myhist(ax0, 'blue')
myhist(ax1, 'green')

say_something(ax0, 'this is the blue plot')
say_something(ax1, 'this is the green plot')

plt.show()

alt text

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

4 Comments

You're welcome! To format the code, indent the whole code block by four extra spaces, and use spaces instead of tabs within your code. There's more on formatting here: stackoverflow.com/editing-help
Why don't myhist() and say_something() have to return ax back into the outer namespace?
@RovingRichard: Python passes by reference, so the two fcns act on the objects that are passed into them, which are the same objects (eg, have same id) as in the global namespace. (I hope this answers your question, but if it doesn't, you'd need to say why you think the fcns would have to return ax.)
@tom10 D'oh! This whole time I thought when I pass object1 to a function, the function created it's own namespace with a copy object2, and that if I wanted to update the object1 I had to return object2.
0

Okey, I've figured out how to do this. It was a lot simpler than what I had imagined. It just required a bit of reading here with the figure and axes classes.

In your main script:

import pylab as plt  
import DrawFns  
fig = plt.figure()  
(do something with fig)  
DrawFns.WriteText(fig, 'Testing')  
plt.show()

In your DrawFns.py:

def WriteText(_fig, _text):  
[indent]_fig.text(0, 0, _text)

And that's it! And I can add more functions in DrawFns.py and call them from any script as long as they are included with import call. :D

2 Comments

This is the right idea, except generally the figure contains one or more axes and most of the action is in calling the axes methods to make your plots, so it's easier to make the figure, then the axes, and pass the axes (or some object within them) to the functions. See my answer for an example.
Sorry, I just saw this. Thanks for the tip. I'll change the code accordingly (offline). Thank you!

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.