Matplotlib with an odd number of subtitles

I am trying to create a graph plotting function that takes as input the number of graphs required and calculates them using the pylab.subplots and sharex=True parameters. If the number of required graphs is odd, then I would like to remove the last panel and force the label to be set in the panel on the right above it. I cannot find a way to do this and use the sharex=True parameter at the same time. The number of subheadings can be quite large (> 20).

Here is a sample code. In this example, I want to force shortcut labels when i=3 .

 import numpy as np import matplotlib.pylab as plt def main(): n = 5 nx = 100 x = np.arange(nx) if n % 2 == 0: f, axs = plt.subplots(n/2, 2, sharex=True) else: f, axs = plt.subplots(n/2+1, 2, sharex=True) for i in range(n): y = np.random.rand(nx) if i % 2 == 0: axs[i/2, 0].plot(x, y, '-', label='plot '+str(i+1)) axs[i/2, 0].legend() else: axs[i/2, 1].plot(x, y, '-', label='plot '+str(i+1)) axs[i/2, 1].legend() if n % 2 != 0: f.delaxes(axs[i/2, 1]) f.show() if __name__ == "__main__": main() 
+7
source share
4 answers

If you replace the last if in your main function as follows:

 if n % 2 != 0: for l in axs[i/2-1,1].get_xaxis().get_majorticklabels(): l.set_visible(True) f.delaxes(axs[i/2, 1]) f.show() 

He should do the trick:

Plot

+8
source

Simply put, you force your subplots to call an even number (in this case, 6 sections):

 f, ax = plt.subplots(3, 2, figsize=(12, 15)) 

Then you delete the one you don't need:

 f.delaxes(ax[2,1]) #The indexing is zero-based here 

This question and answer is considered automatically, but I thought it was worth publishing the main use case here.

+1
source

I constantly generate an arbitrary number of auxiliary sections (sometimes the data leads to 3 sections, sometimes to 13, etc.). I wrote a small utility function to stop thinking about it.

The two functions that I define are as follows. You can change the stylistic choice to suit your preferences.

 import math import numpy as np from matplotlib import pyplot as plt def choose_subplot_dimensions(k): if k < 4: return k, 1 elif k < 11: return math.ceil(k/2), 2 else: # I've chosen to have a maximum of 3 columns return math.ceil(k/3), 3 def generate_subplots(k, row_wise=False): nrow, ncol = choose_subplot_dimensions(k) # Choose your share X and share Y parameters as you wish: figure, axes = plt.subplots(nrow, ncol, sharex=True, sharey=False) # Check if it an array. If there only one plot, it just an Axes obj if not isinstance(axes, np.ndarray): return figure, [axes] else: # Choose the traversal you'd like: 'F' is col-wise, 'C' is row-wise axes = axes.flatten(order=('C' if row_wise else 'F')) # Delete any unused axes from the figure, so that they don't show # blank x- and y-axis lines for idx, ax in enumerate(axes[k:]): figure.delaxes(ax) # Turn ticks on for the last ax in each column, wherever it lands idx_to_turn_on_ticks = idx + k - ncol if row_wise else idx + k - 1 for tk in axes[idx_to_turn_on_ticks].get_xticklabels(): tk.set_visible(True) axes = axes[:k] return figure, axes 

And here is an example of use with 13 plots:

 x_variable = list(range(-5, 6)) parameters = list(range(0, 13)) figure, axes = generate_subplots(len(parameters), row_wise=True) for parameter, ax in zip(parameters, axes): ax.plot(x_variable, [x**parameter for x in x_variable]) ax.set_title(label="y=x^{}".format(parameter)) plt.tight_layout() plt.show() 

Which produces the following:

enter image description here

Or, switching to the column traversal order ( generate_subplots(..., row_wise=False) ) generates:

enter image description here

0
source

For Python 3, you can remove as shown below:

 # I have 5 plots that i want to show in 2 rows. So I do 3 columns. That way i have 6 plots. f, axes = plt.subplots(2, 3, figsize=(20, 10)) sns.countplot(sales_data['Gender'], order = sales_data['Gender'].value_counts().index, palette = "Set1", ax = axes[0,0]) sns.countplot(sales_data['Age'], order = sales_data['Age'].value_counts().index, palette = "Set1", ax = axes[0,1]) sns.countplot(sales_data['Occupation'], order = sales_data['Occupation'].value_counts().index, palette = "Set1", ax = axes[0,2]) sns.countplot(sales_data['City_Category'], order = sales_data['City_Category'].value_counts().index, palette = "Set1", ax = axes[1,0]) sns.countplot(sales_data['Marital_Status'], order = sales_data['Marital_Status'].value_counts().index, palette = "Set1", ax = axes[1, 1]) # This line will delete the last empty plot f.delaxes(ax= axes[1,2]) 
-1
source

Source: https://habr.com/ru/post/983034/


All Articles