Attach matplot.figure.Figure to pyplot - python

TL;DR:
I would like to output a matplotlib.figure.Figure instance with matplotlib.pyplot.
Long version:
I have a function that returns a matplotlib.figure.Figure instance. The function adds some data to the figure, but does not yet show the graph. Thus, it is possible to decide afterwards what backend should be used to output the figure. I was able to find out how to do draw the graph with tkinter, and it shouldn't be much of a problem to do the same with other backends. But, and that is my problem, I couldn't find out how to draw the figure with a simple pyplot command. How should I do this?

Related

Data visualization in python (matplotlib) [duplicate]

I'm not really new to matplotlib and I'm deeply ashamed to admit I have always used it as a tool for getting a solution as quick and easy as possible. So I know how to get basic plots, subplots and stuff and have quite a few code which gets reused from time to time...but I have no "deep(er) knowledge" of matplotlib.
Recently I thought I should change this and work myself through some tutorials. However, I am still confused about matplotlibs plt, fig(ure) and ax(arr). What is really the difference?
In most cases, for some "quick'n'dirty' plotting I see people using just pyplot as plt and directly plot with plt.plot. Since I am having multiple stuff to plot quite often, I frequently use f, axarr = plt.subplots()...but most times you see only code putting data into the axarr and ignoring the figure f.
So, my question is: what is a clean way to work with matplotlib? When to use plt only, what is or what should a figure be used for? Should subplots just containing data? Or is it valid and good practice to everything like styling, clearing a plot, ..., inside of subplots?
I hope this is not to wide-ranging. Basically I am asking for some advice for the true purposes of plt <-> fig <-> ax(arr) (and when/how to use them properly).
Tutorials would also be welcome. The matplotlib documentation is rather confusing to me. When one searches something really specific, like rescaling a legend, different plot markers and colors and so on the official documentation is really precise but rather general information is not that good in my opinion. Too much different examples, no real explanations of the purposes...looks more or less like a big listing of all possible API methods and arguments.
pyplot is the 'scripting' level API in matplotlib (its highest level API to do a lot with matplotlib). It allows you to use matplotlib using a procedural interface in a similar way as you can do it with Matlab. pyplot has a notion of 'current figure' and 'current axes' that all the functions delegate to (#tacaswell dixit). So, when you use the functions available on the module pyplot you are plotting to the 'current figure' and 'current axes'.
If you want 'fine-grain' control of where/what your are plotting then you should use an object oriented API using instances of Figure and Axes.
Functions available in pyplot have an equivalent method in the Axes.
From the repo anatomy of matplotlib:
The Figure is the top-level container in this hierarchy. It is the overall window/page that everything is drawn on. You can have multiple independent figures and Figures can contain multiple Axes.
But...
Most plotting occurs on an Axes. The axes is effectively the area that we plot data on and any ticks/labels/etc associated with it. Usually we'll set up an Axes with a call to subplot (which places Axes on a regular grid), so in most cases, Axes and Subplot are synonymous.
Each Axes has an XAxis and a YAxis. These contain the ticks, tick locations, labels, etc.
If you want to know the anatomy of a plot you can visit this link.
I think that this tutorial explains well the basic notions of the object hierarchy of matplotlib like Figure and Axes, as well as the notion of current figure and current Axes.
If you want a quick answer: There is the Figure object which is the container that wraps multiple Axes(which is different from axis) which also contains smaller objects like legends, line, tick marks ... as shown in this image taken from matplotlib documentation
So when we do
>>> import matplotlib.pyplot as plt
>>> fig, ax = plt.subplots()
>>> type(fig)
<class 'matplotlib.figure.Figure'>
>>> type(ax)
<class 'matplotlib.axes._subplots.AxesSubplot'>
We have created a Figure object and an Axes object that is contained in that figure.
pyplot is matlab like API for those who are familiar with matlab and want to make quick and dirty plots
figure is object-oriented API for those who doesn't care about matlab style plotting
So you can use either one but perhaps not both together.

Get the limits of matplotlib interactive plot

In my plotting application written in Python, I use matplotlib (with TkAgg backend) to draw some data.
This plot is interactive, so the user can drag/zoom the plot region. However, sometimes the application needs to clear the curves and plot them anew - and as a result, the plot rescales to the extent of the curves.
It would be better to keep the user-defined limits. However, calling e.g. ax.get_xlim() returns the limits that were originally set by ax.set_xlim(...), not the current limits that the user has changed by their mouse.
I tried hard to find the solution in the documentation and examples, yet still I could not resolve this simple task: How to get the current limits of interactive matplotlib plot?

How to create a reusable basemap

In continuation to my previous question: How to superimpose figures in matplotlib i would like to know how can one create a reusable basemap object.
My problem is that a basemap is not a pyplot object, so the solution i received works well on figures / axes but not on basemap objects.
I tried to look around and find a solution, but couldn't find any, just discussions.
Thanks to #JoeKington here and #EdSmith at How to superimpose figures in matplotlib, i was able to understand how to achieve what i wanted: reuse basemap objects and pass them around.
I made it this way:
Created a base_map.py that has two functions: plot() that create a map object and draw some properties and another one, set_a_map() that create an empty map object.
In the other modules i added to the plot functions a map=None property, and in each function i added a:
if not map:
map = base_map.set_a_map()
So that in case that no map object being passed to the other function, the function will create a new map object.
In my plot functions, instead of using plt.imshow(...) for example, i'm using map.imshow(...). This way my data will be plot over a map.
Thank you for the patience and the really helpful comments!

matplotlib plot whole data

I've been using matplotlib to plot data in the form of lines.
I want all of the data to be visible at any time, but mpl is giving me strange behaviour while fine zooming:
First image: http://i.stack.imgur.com/nccvi.png
Second image: http://i.stack.imgur.com/hov79.png
The data is not consistent between different views, and I can't allow that in my application. What can I do to prevent this?
I can't find any method to tell mpl to plot all of the data, it seems that there are only methods for drawing every n'th element or similar (and passing 1 does not help).
NOTE: I am using the Qt backend.

matplotlib gui respond to axes changes

I have created a little GUI with QT which set's up a single matplotlib figure and axes.
The GUI has controls to change just about everything to do with the appearance of the axes.
Basically, it does this by each widget emitting signals back up to the main frame and it calls the appropriate matplotlib setters on the axes and figure objects.
However, it is possible for the axes (and therefore the image displayed on the FigureCanvas) to change without input from the GUI (e.g. when autoscaling, or adding certain plots which adjust the axes automatically).
In this case, a widget controlling e.g. the limits of the x axis will now be displaying the wrong values.
I would like all the relevant widgets to update when the axes updates....how could I possible achieve this?
I'm thinking that this is a problem that has been solved before - how to enable a two-way communication between distinct objects?
fig.canvas.draw()
time.sleep(1e-2)
whenever anything writes to the plot? however it's hard to help with no code.
Showing an example of how your code is not working would help a lot.
EDIT:
I'll try this again then:
What about getting the state of the plot you are updating? I guess its what #Ajean means by updater method. I know that Artists in matplotlib have an Artist.properties() method that returns all of the properties and values.
I imagine Axes would have a similar method.
A quick look at the matplotlib docs yielded 2 interesting methods of axes:
ax.get_autoscale_on()
and
ax.set_autoscale_on().
ax.set_autoscale_on(False) will prevent plots from updating the state of the axes.

Categories

Resources