Spacing Between Subplots in Matplotlib Python - python

I have subplots that come in pairs and then are stacked. I have them dynamically build based on how many runs I do (2 subplots side by side per run).
These subplots have titles on top (default position).
What I am running into is that the second pair's title, which resides under the first pair, is over lapping with the x-axis of the first pair.
I have tried tight_layout however it squished my graphs to the point of them being unusable.
I am looking for a way to stack pairs of subplots with enough room inbetween to have titles. Is there any way to add padding in between the stacked pairs. I also tried subplots_adjust(bottom=0.2) but that didn't work either.
I figured this would be a lot easier.

Related

Possible to matplotlib's constrained_layout ignore axis tick labels?

I have a reasonably complicated grid of subplots that involves two sets (one on the left and another on the right) of columns plotting a set of quantities for each row, separated by a common legend to label the entries in each row.
Here is a sample of what I want to accomplish
Using matplotlib with constrained_layout = True works 95% perfectly for applying the out optimal sizes & spacing for the columns, down to the tricky case of having the legend run down the middle. The remaining 5% is highlighted in red, where the wordy x-axis tick labels seem to push away the columns: it would be perfect if there was a way to make the layout engine "ignore" the tick labels in determining the spacing.
Methods using other libraries are also appreciated. Thank you in advance.
What I tried:
subplots_adjust
GridSpec
The main difficulty with those attempts:
constrained_layout is incompatible with those settings, so one must sacrifice the optimized legend spacing at the cost of getting the column spacing right, or vice versa.

Matplotlib savefig bbox_inches='tight' along a single direction only?

I have two plots, each with multiple subplots (panels), i.e. multiple rows and columns. Each row shows the same type of data as images with colorbars on the right side. The first plot has, say, 8 rows and 4 columns. The second one has, say, 3 rows and 4 columns. The two plots are inserted into a LaTeX pdf document on two consecutive pages, with the same width (\includegraphics[width=\hsize]{fig1.pdf}). For layout reasons, I want the panels to have exactly the same width and height when flipping between pages in a pdf reader. To guarantee this, I thus used the same subplot layout of 8 x 4 panels for the second plot and made the panels (axes) for the 5 rows where there are no data invisible.
Since the second plot has only 3 rows of data, I use fig.savefig(bbox_inches='tight') to clip the white space below those rows. Unfortunately, as the ticks on the colorbar on the right side of the last column have a different maximum number of digits (on the first and second plot, say 1 and 2 decimal digits), with bbox_inches='tight' the resulting figure width (after saving and thus also when included into the LaTeX pdf) becomes different between the two plots.
I would like to not have to use a different layout of 3 x 4 subplots for the second plot, where I have to manually adjust the figure height (and likely still don't get exactly the same panel sizes). I could adjust both the tick formatters and tick locators on the colorbars to the same maximum number of digits for the two plots, but I would prefer to let matplotlib use the default ScalarFormatter() and AutoLocator().
Optimally, I would like to clip the white space below the 3 rows for the y-direction using bbox_inches='tight', but leave the bbox untouched for the x-direction and manually adjust the right figure border via fig.subplot_params(fig_right) to the same value for the two plots.
Questions: Is it possible to use bbox_inches='tight' only for the y-direction of a figure, but use the default bbox_inches (rcParams['savefig.bbox'], defaults to None) for the x-direction? Should such a feature (accepted values 'tight_x' and 'tight_y' for bbox_inches) maybe be implemented to matplotlib (I assume (but don't know) that this would not be too difficult)? Do you have alternative ideas how I can obtain exactly the same panel sizes for the two plots?
Update from original poster: As noted by #Jody Klymak, it is not possible to use a tight bounding box for one direction (or one border) only, but custom bounding boxes may be used. In my case, I pass bbox_inches=None for the first plot, and bbox_inches=Bbox([[0,fig.get_tightbbox(fig.canvas.get_renderer())._bbox.y0/fig.dpi - 0.1],[fig.get_figwidth(),fig.get_figheight()]]) for the second plot. This solves the question.

Adjusting width of single data barplot

I am automating making reports based on particular locations. Certain graphs contain bar graphs with only one bar and they span the width of the graph. I tried using axes.set_xlim(0, len(data)-1) but ended up with the graph looking like the top one in the attached picture, if there are more than one bars. When I have multiple bars, usually leaving out axes.set_xlim gives a decent graph (last graph in picture). I know using width in the graph will only work is there are two or more bars.
I used len(data) since data is a list and the length would tell me how many bars are going to pop up.
My graph code is within a for loop, so each iteration will have a different length for data
Is there a way to adjust the widths accordingly?

Plotting multiple Figures with Plot.ly

I have a plot that graphs multiple datasets against time, over several different generations. A slider controls the generation. The way I'm accomplishing this right now is by making (Number of Generations * Number of Lines) scatter plots in a list that I pass in to plotly.offline.plot. This makes creating the generation slider pretty difficult and full of annoying bugs (like the legend changing order for each generation).
My question is this: Is there some way I can group multiple scatter plots (like with a Figure) and pass in a list of those groups in to plotly.offline.plot?

On adjusting margins in matplotlib

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

Categories