On adjusting margins in matplotlib - python

I am trying to minimize margins around a 1X2 figure, a figure which are two stacked subplots. I searched a lot and came up with commands like:
self.figure.subplots_adjust(left=0.01, bottom=0.01, top=0.99, right=0.99)
Which leaves a large gap on top and between the subplots. Playing with these parameters, much less understanding them was tough (things like ValueError: bottom cannot be >= top)
My questions :
What is the command to completely minimize the margins?
What do these numbers mean, and what coordinate system does this follow (the non-standard percent thing and origin point of this coordinate system)? What are the special rules on top of this coordinate system?
Where is the exact point this command needs to be called? From experiment, I figured out it works after you create subplots. What if you need to call it repeatedly after you resize a window and need to resize the figure to fit inside?
What are the other methods of adjusting layouts, especially for a single subplot?

They're in figure coordinates: http://matplotlib.sourceforge.net/users/transforms_tutorial.html
To remove gaps between subplots, use the wspace and hspace keywords to subplots_adjust.
If you want to have things adjusted automatically, have a look at tight_layout
Gridspec: http://matplotlib.sourceforge.net/users/gridspec.html

Related

Plotting points within a triangle

I'm using Python, and I have some data which can be projected on to points within an equilateral triangle whose side lengths sum to 1.
I'm not sure if there is an easy way to visualise a plot like this from Matplotlib or similar libraries, or if I'm just going to have to use a drawing package from scratch to make it happen. Any pointers gratefully recieved. Thanks!
If all you want to do is plot a few dots on a graph, you can infact use Matfplotlib's scatter plots for this:
https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.scatter.html
Using plt.xlim(*min*, *max*) and plt.ylim(*min*, *max*), you can set the limits of the graph manually to fit your values (might not be neccessary though).
You can draw lines on the graph for the triangle shape (if you need that): How to draw a line with matplotlib?
If you don't need a scale, you can even remove that to have a blank canvas: Matplotlib plots: removing axis, legends and white spaces

Matplotlib - tight layout placement and adjusting padding

I am running a function that runs multiple sub-functions, each calling for an axis in a plot (for example, a 2x2 matplotlib subplot). While the figure is working out, I'd like to reduce some of the padding, notably for the x axis. Is there anything I can do to minimize some space and offer more room in the plots for the data to be seen?
Currently, I am calling plt.tight_layout(pad=0.1, w_pad=0.05, h_pad=0.05) at the end prior to calling plt.show() and plotting; should I opt to use for whenever an axis is established instead? I am also using the labelpad modifier when generated each axis title; however, this is done as part of each sub-function that works on its own axis and tight_layout() is called at the end, so perhaps it is pointless?
Finally, here is what I am able to get with the above padding settings, and I cannot seem to improve it. Any suggestions for alternative ideas?

subplot using automatic resizing

looking for some "magic" command that make the maps of the subplots (2x2 in my case) well speared not too much but with the right spacing in order to be considered "quality plot" I found that i can set all using the option rect inside plt.tight_layout I spend time to find this parameters : plt.tight_layout(rect=(0.02,0.02,0.97,0.97))
Now the plot is fitting well the pdf image but the 2 plots of the top is to close to the 2 below look the picture without going out of bound on the top ? and how can obtain the plot title a bit more separate respect the figure ? hope in your hint !
EDIT ok .. if I use the command plt.title('...',y=1.1) this is taken just on the last plot (the axs[1,1]) while I'm write the command before all the subplot !
Sorry I don't have an answer for automatic resizing but since you asked for some hints, there is one possible solution:
https://matplotlib.org/api/_as_gen/matplotlib.pyplot.subplots_adjust.html
What you need is wspace for horizontal spacing and hspace for horizontal spacing between the subplots. This gives you freedom to choose the desired spacing to make your plot a "quality plot". Hope it helps.
As to your second question about placing the title, you can use:
plt.title("Title here", y=1.25)
where y defines the position of your title in relative coordinates. y=1 would mean at the top x-axis and y=0.5 would mean in the centre of the plot. Since you have a title for each subplot, you can use the respective relative coordinates for each.

Python: how to plot points with little overlapping

I am using python to plot points. The plot shows relationship between area and the # of points of interest (POIs) in this area. I have 3000 area values and 3000 # of POI values.
Now the plot looks like this:
The problem is that, at lower left side, points are severely overlapping each other so it is hard to get enough information. Most areas are not that big and they don't have many POIs.
I want to make a plot with little overlapping. I am wondering whether I can use unevenly distributed axis or use histogram to make a beautiful plot. Can anyone help me?
I would suggest using a logarithmic scale for the y axis. You can either use pyplot.semilogy(...) or pyplot.yscale('log') (http://matplotlib.org/api/pyplot_api.html).
Note that points where area <= 0 will not be rendered.
I think we have two major choices here. First adjusting this plot, and second choosing to display your data in another type of plot.
In the first option, I would suggest clipping the boundries. You have plenty of space around the borders. If you limit the plot to the boundries, your data would scale better. On top of it, you may choose to plot the points with smaller dots, so that they would seem less overlapping.
Second option would be to choose displaying data in a different view, such as histograms. This might give a better insight in terms of distribution of your data among different bins. But this would be completely different type of view, in regards to the former plot.
I would suggest trying to adjust the plot by limiting the boundries of the plot to the data points, so that the plot area would have enough space to scale the data and try using histograms later. But as I mentioned, these are two different things and would give different insights about your data.
For adjusting you might try this:
x1,x2,y1,y2 = plt.axis()
plt.axis((x1,x2,y1,y2))
You would probably need to make minor adjustments to the axis variables. Note that there should definetly be better options instead of this, but this was the first thing that came to my mind.

Need to add a "legend" to an arrow/contour plot

I am plotting some scalar data as a contour plot with matplotlib.contourf. On top of it, I am plotting some vector data with matplotlib.arrow. The basic plot has come along OK, but now I need to put a box on the plot with a default-size arrow plus the data value to which it corresponds, so the viewer will know what kind of scale he is looking at. For instance, I need a box with a horizontal arrow of some length and, below that, some text like "10 cm/sec".
First, if anyone can give me a simple approach to this, I would be grateful.
Second, the approach I have tried is to do the contour plot, then plot the arrows, then add a rectangle to the plot like so:
rect=pl.Rectangle((300,70),15,15,fc='white')
pl.gca().add_patch(rect)
and then, finally, put my scale arrow and text on top of this rectangle.
This isn't working because the rectangle patch covers up the contour, but it doesn't cover up the arrows in the plot. Is there a way to move the patch completely "to the front" of everything else?
Got it. Using pylab.quiver and pylab.quiverkey functions. quiver produces a nice vector field with just a few lines of code, and quiverkey makes it easy to produce a scaling vector with text. And, for some reason, the arrows plotted with quiver are indeed covered by my rectangle, so it is easy to make the scaling arrow very visible. There are still some mysteries in all of this for me. If anyone wants to try to clear them up, would be much obliged. But I have a way now to do what I need in this instance.

Categories