how to make Y-label of subplots to appear only once? - python

I have a simple problem i need to solve, here is the example
import matplotlib.pyplot as plt
fig, ax = plt.subplots(nrows=1, ncols=3, figsize=(6, 6))
for axs in ax.flat:
axs.set(ylabel='AUC')
this is the output
I want Y-label(AUC) to appear only once(be shared) at the first subplot, and other values should remain. This is the desired output
How to solve this? Please I need your help

Since you're setting your labels in a loop, you're labeling all the axes in your subplots accordingly. What you need is to only label the first cell in your subplot row.
So this:
for axs in ax.flat:
axs.set(ylabel='AUC')
changes to:
ax[0].set_ylabel("AUC")
I also recommend you to share the axis between your multiple subplots, since all the yticks are making your plot a little less readable than ideal. You can change it as below:
fig, ax = plt.subplots(nrows=1, ncols=3, figsize=(6, 6), sharex=True, sharey=True,)
The resulting image will be:

Related

How can i show the output of pies side by side?

I have following code which gives the output one below another. How can i show the output side by side? I will also add anouther pies in to this code, so i also want to know how would it be if i wanted to show 6 pies for instance.
Thanks in advance
data["Gender"].value_counts().plot.pie(autopct="%.1f%%")
plt.show()
data["Education_Level"].value_counts().plot.pie(autopct="%.1f%%")
You can create a subplot with a specification of your own, and then pass the current axis as a parameter. Here I'll create a subplot with 1 row and 2 columns:
import pandas as pd
import matplotlib.pyplot as plt
df = pd.DataFrame({'mass': [0.33, 4.87, 5.97],
'radius': [2439.7, 6051.8, 6378.1]},
index=['Mercury', 'Venus', 'Earth']
)
fig, axs = plt.subplots(nrows=1, ncols=2, figsize=(12, 12))
df.plot.pie(y='mass', ax=axs[0])
df.plot.pie(y='radius', ax=axs[1])
plt.show()
The code above produces the following result:
In case you wanted 6 figures next to each other, set the ncols parameter to 6, and then pass through all 6 axes. Here's a quick demo.
fig, axs = plt.subplots(nrows=1, ncols=6, figsize=(12, 12))
for ax in axs:
df.plot.pie(y='mass', ax=ax) # plots the same pie 6 times
Be sure to read more about matplotlib and how figures/axes work from their documentation.

Move ticks and labels to the top of a pyplot figure

As per this question, moving the xticks and labels of an AxesSubplot object can be done with ax.xaxis.tick_top(). However, I cannot get this to work with multiple axes inside a figure.
Essentially, I want to move the xticks to the very top of the figure (only displayed at the top for the subplots in the first row).
Here's a silly example of what I'm trying to do:
fig, axs = plt.subplots(nrows=2, ncols=2, sharex=True, sharey=True)
fig.set_figheight(5)
fig.set_figwidth(10)
for ax in axs.flatten():
ax.xaxis.tick_top()
plt.show()
Which shows
My desired result is this same figure but with the xticks and xticklabels at the top of the two plots in the first row.
Credits to #BigBen for the sharex comment. It is indeed what's preventing tick_top to work.
To get your results, you can combine using tick_top for the two top plots and use tick_params for the bottom two:
fig, axs = plt.subplots(2, 2, sharex=False) # Do not share xaxis
for ax in axs.flatten()[0:2]:
ax.xaxis.tick_top()
for ax in axs.flatten()[2:]:
ax.tick_params(axis='x',which='both',labelbottom=False)
See a live implementation here.

Axes.invert_axis() does not work with sharey=True for matplotlib subplots

I am trying to make 4 subplots (2x2) with an inverted y axis while also sharing the y axis between subplots. Here is what I get:
import matplotlib.pyplot as plt
import numpy as np
fig,AX = plt.subplots(2, 2, sharex=True, sharey=True)
for ax in AX.flatten():
ax.invert_yaxis()
ax.plot(range(10), np.random.random(10))
It appears that ax.invert_axis() is being ignored when sharey=True. If I set sharey=False I get an inverted y axis in all subplots but obviously the y axis is no longer shared among subplots. Am I doing something wrong here, is this a bug, or does it not make sense to do something like this?
Since you set sharey=True, all three axes now behave as if their were one. For instance, when you invert one of them, you affect all four. The problem resides in that you are inverting the axes in a for loop which runs over an iterable of length four, you are thus inverting ALL axes for an even number of times... By inverting an already inverted ax, you simply restore its original orientation. Try with an odd number of subplots instead, and you will see that the axes are successfully inverted.
To solve your problem, you should invert the y-axis of one single subplot (and only once). Following code works for me:
import matplotlib.pyplot as plt
import numpy as np
fig,AX = plt.subplots(2, 2, sharex=True, sharey=True)
## access upper left subplot and invert it
AX[0,0].invert_yaxis()
for ax in AX.flatten():
ax.plot(range(10), np.random.random(10))
plt.show()

Share axes in matplotlib for only part of the subplots

I am having a big plot where I initiated with:
import numpy as np
import matplotlib.pyplot as plt
fig, axs = plt.subplots(5, 4)
And I want to do share-x-axis between column 1 and 2; and do the same between column 3 and 4. However, column 1 and 2 does not share the same axis with column 3 and 4.
I was wondering that would there be anyway to do this, and not sharex=True and sharey=True across all figures?
PS: This tutorial does not help too much, because it is only about sharing x/y within each row/column; they cannot do axis sharing between different rows/columns (unless share them across all axes).
I'm not exactly sure what you want to achieve from your question. However, you can specify per subplot which axis it should share with which subplot when adding a subplot to your figure.
This can be done via:
import matplotlib.pylab as plt
fig = plt.figure()
ax1 = fig.add_subplot(5, 4, 1)
ax2 = fig.add_subplot(5, 4, 2, sharex = ax1)
ax3 = fig.add_subplot(5, 4, 3, sharex = ax1, sharey = ax1)
A slightly limited but much simpler option is available for subplots. The limitation is there for a complete row or column of subplots.
For example, if one wants to have common y axis for all the subplots but common x axis only for individual columns in a 3x2 subplot, one could specify it as:
import matplotlib.pyplot as plt
fig, ax = plt.subplots(3, 2, sharey=True, sharex='col')
One can manually manage axes sharing using a Grouper object, which can be accessed via ax._shared_x_axes and ax._shared_y_axes. For example,
import matplotlib.pyplot as plt
def set_share_axes(axs, target=None, sharex=False, sharey=False):
if target is None:
target = axs.flat[0]
# Manage share using grouper objects
for ax in axs.flat:
if sharex:
target._shared_x_axes.join(target, ax)
if sharey:
target._shared_y_axes.join(target, ax)
# Turn off x tick labels and offset text for all but the bottom row
if sharex and axs.ndim > 1:
for ax in axs[:-1,:].flat:
ax.xaxis.set_tick_params(which='both', labelbottom=False, labeltop=False)
ax.xaxis.offsetText.set_visible(False)
# Turn off y tick labels and offset text for all but the left most column
if sharey and axs.ndim > 1:
for ax in axs[:,1:].flat:
ax.yaxis.set_tick_params(which='both', labelleft=False, labelright=False)
ax.yaxis.offsetText.set_visible(False)
fig, axs = plt.subplots(5, 4)
set_share_axes(axs[:,:2], sharex=True)
set_share_axes(axs[:,2:], sharex=True)
To adjust the spacing between subplots in a grouped manner, please refer to this question.
I used Axes.sharex /sharey in a similar setting
https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.sharex.html#matplotlib.axes.Axes.sharex
import matplotlib.pyplot as plt
fig, axd = plt.subplot_mosaic([list(range(3))] +[['A']*3, ['B']*3])
axd[0].plot([0,0.2])
axd['A'].plot([1,2,3])
axd['B'].plot([1,2,3,4,5])
axd['B'].sharex(axd['A'])
for i in [1,2]:
axd[i].sharey(axd[0])
plt.show()

Matplotlib: reorder subplots

Say that I have a figure fig which contains two subplots as in the example from the documentation:
I can obtain the two axes (the left one being ax1 and the right one ax2) by just doing:
ax1, ax2 = fig.axes
Now, is it possible to rearrange the subplots? In this example, to swap them?
Sure, as long as you're not going to use subplots_adjust (and therefore tight_layout) after you reposition them (you can use it safely before).
Basically, just do something like:
import matplotlib.pyplot as plt
# Create something similar to your pickled figure......
fig, (ax1, ax2) = plt.subplots(ncols=2)
ax1.plot(range(10), 'r^-')
ax1.set(title='Originally on the left')
ax2.plot(range(10), 'gs-')
ax2.set(title='Originally on the right')
# Now we'll swap their positions after they've been created.
pos1 = ax1.get_position()
ax1.set_position(ax2.get_position())
ax2.set_position(pos1)
plt.show()

Categories

Resources