matplotlib how is a figure structured? - python

So I'm trying to understand how a figure is structured. My understanding is the following:
you have a canvas (if you've got a gui or something similar), a figure, and axes
you add the axes to the figure, and the figure to the canvas.
The plot is held by the axes, so for example:
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot([1, 2], [1, 4])
fig.show()
I would expect would create a figure however I just get a blank window... Also, it seems canvas is not needed at all?
any help appreciated thank you!
here it says the above code should work... or has a similar example
https://github.com/thehackerwithin/PyTrieste/wiki/Python7-MatPlotLib

You shouldn't be poking at the canvas unless you really know what you are doing (and are embedding mpl into another program). pyplot has a bunch of nice tools that takes care of most of the set up for you.
There is a separation between the user layer (figures, axes, artists, and such) and the rendering layer (canvas, renderer, and such). The first layer is user facing and should be machine independent. The second layer is machine specific, but should expose none of that to
the user.
There are a varity of 'backends' that take care of the translation between the two layers (by providing sub-classes of canvas and such). There are interactive backends (QtAgg, GtkAgg, TkAgg,...) which include all the hooks into a gui toolkit to provide nice windows and non-interactive backend (PS, pdf, ...) that only save files.
figures hold axes which hold artists (and axis). Those classes will talk to the rendering layer, but you (for the most part) do not need to worry about exactly how.

Related

How to make plots customizable in python

I have two issues with my python plot that would be grateful if anyone could help me with:
1- I wonder if it is possible in python to have the option for the plots after display to add horizontal or vertical lines, so that these new lines could be added, moved or deleted without the need to run the code again.
to say it more clearly, I am looking for additional features that adding them does not need to change the code and they only enable me to manually draw on the already plotted image.
2- I want to plot a very large image in the real size, So that I need to add the horizontal and vertical slide bars to be able to scroll up/down or left/right in the plot?
I need to combine these two ability for my project, can someone help me with that?
1- You can't physically draw on it, but you can make a plot in matplotlib interactive as follows:
import matplotlib.pyplot as plt
plt.ion() # turns on interactive mode
fig = plt.figure()
ax = fig.add_subplot()
plt.ylim(-10, 10)
plt.xlim(0, 10)
while True:
plt.axhline(float(input("number")))
fig.canvas.draw()
fig.canvas.flush_events() # draws
This program allows you to create horizontal lines based on user input.
I think you can solve 2 with tkinter, but that would be pretty difficult. There might also an easier way. See this stack overflow question for an example of an interactive plot in tkinter. I believe this plot can be made bigger and scrollable, but I am not sure.

I use the subplot module to draw multiple subplots, But error with'list' object has no attribute'set_xlim' [duplicate]

What is the difference between the Axes.plot() and pyplot.plot() methods? Does one use another as a subroutine?
It seems that my options for plotting are
line = plt.plot(data)
or
ax = plt.axes()
line = ax.plot(data)
or even
fig = plt.figure()
ax = fig.add_axes([0,0,1,1])
line = ax.plot(data)
Are there situations where it is preferable to use one over the other?
For drawing a single plot, the best practice is probably
fig = plt.figure()
plt.plot(data)
fig.show()
Now, lets take a look in to 3 examples from the question and explain what they do.
Takes the current figure and axes (if none exists it will create a new one) and plot into them.
line = plt.plot(data)
In your case, the behavior is same as before with explicitly stating the
axes for plot.
ax = plt.axes()
line = ax.plot(data)
This approach of using ax.plot(...) is a must, if you want to plot into multiple axes (possibly in one figure). For example when using a subplots.
Explicitly creates new figure - you will not add anything to previous one.
Explicitly creates a new axes with given rectangle shape and the rest is the
same as with 2.
fig = plt.figure()
ax = fig.add_axes([0,0,1,1])
line = ax.plot(data)
possible problem using figure.add_axes is that it may add a new axes object
to the figure, which will overlay the first one (or others). This happens if
the requested size does not match the existing ones.
There is essentially no difference. plt.plot will at some point (after making sure that there is a figure and an axes available to plot to) call the plot function from that axes instance.
So the main difference is rather at the user's side:
do you want to use the Matlab-like state machine approach, which may save some lines of code for simple plotting tasks? Then use pyplot.
do you want to have full control over the plotting using the more pythonic object oriented approach? Then use objects like axes explicitely.
You may want to read the matplotlib usage guide.
Pyplot's plotting methods can be applied to either the Pyplot root (pyplot.plot()) or an axes object (axes.plot()).
Calling a plotting function directly on the Pyplot library (pyplot.plot()) creates a default subplot (figure and axes). Calling it on an axes object (axes.plot()) requires that you to have created your own axes object already and puts the graph onto that customized plotting space.
While pyplot.plot() is easy to use, you have more control over your space (and better able to understand interaction with other libraries) if you create an axes object axes.plot().
Axes.plot() returns an axes object. Every axes object has a parent figure object. The axes object contains the methods for plotting, as well as most customization options, while the figure object stores all of the figure-level attributes and allow the plot to output as an image.
If you use pyplot.plot() method and want to start customizing your axes, you can find out the name of the default axes object it created by calling pyplot.gca() to "get current axes."
python plt.plot(): it will create many default subplots, will save many lines of code and is easy to understand.
Axes.plot(): using an axes object will give you a better ability to customize your plot space.
If this is still relevant, Matplotlib's official website has a clear answer on this issue. Go to "The object-oriented interface and pyplot interface".
This section clearly answers the question. Using 'fig, ax', i.e., object-oriented approach gives one more control for customizing our plot. Using 'pyplot', on the other hand leaves us with less control over our plot but the advantage is that it saves us from writing more lines of code and is easier and handy when dealing with single plot.
Official documentation of Matplotlib suggests that "which approach to use is solely an individual's choice and there is no preference of one over other. However, it is good to stick to one approach to maintain consistency."

Do I need a figure? What are they for?

I have begun using matplotlib and I am somewhat confused as to why figures exist. Sometimes I see code where a figure is declared and then a plot is made, and sometimes I see things like this:
import numpy as np
import matplotlib.pyplot as plt
data = np.loadtxt('initial.dat','float')
plt.plot(data[:,0], data[:,1])
plt.xlabel("x (Angstroms)")
plt.ylabel("V (eV)")
plt.savefig('v.png',bbox_inches='tight')
plt.clf()
I read the documentation on figure and plot, but I don't get it. Why do figures exist?
A figure will always exist once you create some plot with matplotlib.
The introductory matplotlib page may help here:
The whole figure. The figure keeps track of all the child Axes, a smattering of ‘special’ artists (titles, figure legends, etc), and the canvas. (Don’t worry too much about the canvas, it is crucial as it is the object that actually does the drawing to get you your plot, but as the user it is more-or-less invisible to you). A figure can have any number of Axes, but to be useful should have at least one.
You can imagine the figure to be the white sheet of paper you draw a plot on. A figure has some size, maybe a background and most importantly it is the container for everything you draw into it. In most cases this will be one or more axes. If there wasn't any figure, there wouldn't be any sheet of paper to draw your plot to (you cannot draw a line in the air).
Even if you haven't explicitely created the figure, it is automatically created in the background.
import matplotlib.pyplot as plt
plt.plot([1,2,3])
# at this point we already have a figure, because the plot needs to live somewhere
# we can get a handle to the figure via
figure = plt.gcf()
Examples of when you explicitely need a figure:
If you want to create a second figure.
plt.plot([1,2,3])
plt.figure(2)
plt.plot([2,4,6])
If you want to set the figure size or other figure parameters.
plt.figure(figsize=(5,4), dpi=72)
If you want to change the padding of the subplot(s).
fig, ax=plt.subplots()
fig.subplots_adjust(bottom=0.2)

Matplotlib-like Subplots in Mayavi?

What I'm looking to do is have a pair of 3D figures side by side.
In matplotlib, I was able to create these subplots like so:
ax1 = fig.add_subplot(121, projection='3d')
I'm trying to use Mayavi for my 3D plotting here, because it solves some other problems I'm having, but I can't seem to find a way to plot two figures side-by-side.
Is this even possible?
Every mayavi actor has position/origin/orientation attributes, which you can set to move them to different parts of the scene. You can also add multiple axes and tailor both the ranges over which they display and the labels output. Using a combination of these, you can solve your question; but no, I don't know of a simple "subplot" mechanism.
Other possible alternatives
mlab.screenshot() on separate scenes and combine them in a custom view.
use the canvas frontend inside your own screen widgets, with each side-by-side widget showing a different scene.

Change dynamically the contents of a matplotlib plot

I while ago, I was comparing the output of two functions using python and matplotlib. The result was as good as simple, since plotting with matplotlib is quite easy: I just plotted two arrays with different markers. Piece of cake.
Now I find myself with the same problem, but now I have a lot of pair of curves to compare. I initially tried plotting everything with different colors and markers. This did not satisfy me since the ranges of each curve are not quite the same. In addition to this, I quickly ran out of colors and markers that were sufficiently different to identify (RGBCMYK, after that, custom colors resemble any of the previous ones).
I also tried subplotting each pair of curves, obtaining a window with many plots. Too crowded.
I tried one window per plot, too many windows.
So I was just wondering if there is any existing widget or if you have any suggestion (or a different idea) to accomplish this:
I want to see a pair of curves and then select easily the next one, with a slidebar, button, mouse scroll, or any other widget or event. By changing curves, the previous one should disappear, the legend should change and its axis as well.
Well I managed to do it with an event handler for mouse clicks. I will change it for something more useful, but I post my solution anyway.
import matplotlib.pyplot as plt
figure = plt.figure()
# plotting
plt.plot([1,2,3],[10,20,30],'bo-')
plt.grid()
plt.legend()
def on_press(event):
print 'you pressed', event.button, event.xdata, event.ydata
event.canvas.figure.clear()
# select new curves to plot, in this example [1,2,3] [0,0,0]
event.canvas.figure.gca().plot([1,2,3],[0,0,0], 'ro-')
event.canvas.figure.gca().grid()
event.canvas.figure.gca().legend()
event.canvas.draw()
figure.canvas.mpl_connect('button_press_event', on_press)
Sounds like you want to embed matplotlib in an application. There are some resources available for that:
user interface examples
Embedding in WX
I really like using traits. If you follow the tutorial Writing a graphical application for scientific programming , you should be able to do what you want. The tutorial shows how to interact with a matplotlib graph using graphical user interface.

Categories