Meghdeep Ray
Meghdeep Ray

Reputation: 5537

Python Matplotlib: Splitting one Large Graph into several Sub-Graphs (Subplot)

Simply put suppose I have 2 lists:
A -> Has the list of names ['A','B','C','D','E','F','G','H']
B -> Has the list of values [5,7,3,8,2,9,1,3]
A will be the names of the X-Axis labels and the corresponding values in B will be the height of the graph ( i.e. the Y-Axis ).

%matplotlib inline
import pandas as pd
from matplotlib import rcParams
import matplotlib.pyplot as plt
from operator import itemgetter

rcParams.update({'figure.autolayout': True})
plt.figure(figsize=(14,9), dpi=600)

reso_names = ['A','B','C','D','E','F','G','H']
reso_values = [5,7,3,8,2,9,1,3]
plt.bar(range(len(reso_values)), reso_values, align='center')
plt.xticks(range(len(reso_names)), list(reso_names), rotation='vertical')

plt.margins(0.075)
plt.xlabel('X-Axis')
plt.ylabel('Y-Axis')
plt.title('Graph', {'family' : 'Arial Black',
        'weight' : 'bold',
        'size'   : 22})
plt.show()

This code gives the following output :enter image description here

However I want it such that it makes subgraphs for every 2 values. In this case there should be 4 subgraphs:

This splitting should be done dynamically (not 4 different loops, it should break the graph into units of 2 each depending on the size of the input, if list A has 10 values then it should give 5 subgraphs).



I figured out how to split the graph into two with half each but I need to achieve it using steps of N per graph (N in this example being 2).
The code I have for breaking the graph into 2 equal subgraphs is :

%matplotlib inline
import pandas as pd
from matplotlib import rcParams
import matplotlib.pyplot as plt
from operator import itemgetter

rcParams.update({'figure.autolayout': True})
plt.figure(figsize=(14,9), dpi=600)

reso_names = ['A','B','C','D','E','F','G','H']
reso_values = [5,7,3,8,2,9,1,3]

fig, axs = plt.subplots(nrows=2, sharey=True, figsize=(14,18), dpi=50)
size = int(len(reso_values))
half = int( size/2 )

fig.suptitle('Graph', 
          **{'family': 'Arial Black', 'size': 22, 'weight': 'bold'})

for ax, start, end in zip(axs, (0, half), (half, size)):
    names, values = list(reso_names[start:end]), reso_values[start:end]
    ax.bar(range(len(values)), values, align='center')
    ax.set_xlabel('X-Axis')
    ax.set_ylabel('Y-Axis')
    ax.set_xticks(range(len(names)))
    ax.set_xticklabels(names, rotation='vertical')
    ax.set_xlim(0, len(names))
fig.subplots_adjust(bottom=0.05, top=0.95)
plt.show()


Which gives me : enter image description here


I just want the program to dynamically split the graphs into subgraphs based on the splitting number N.

Upvotes: 2

Views: 9634

Answers (1)

Yann
Yann

Reputation: 544

You can directly split your lists values/names with size elements into size//N + 1 list of N elements with this code :

N=3
sublists_names = [reso_names[x:x+N] for x in range(0, len(reso_names), N)]
sublists_values = [reso_values[x:x+N] for x in range(0, len(reso_values), N)]

Note that the last sublist will have less elements if N does not divide size.

Then you just perform a zip and plot each sublist in a different graph :

import pandas as pd
from matplotlib import rcParams
import matplotlib.pyplot as plt
from operator import itemgetter

rcParams.update({'figure.autolayout': True})
plt.figure(figsize=(14,9), dpi=600)

reso_names = ['A','B','C','D','E','F','G','H']
reso_values = [5,7,3,8,2,9,1,3]

N=3
sublists_names = [reso_names[x:x+N] for x in range(0, len(reso_names), N)]
sublists_values = [reso_values[x:x+N] for x in range(0, len(reso_values), N)]

size = int(len(reso_values))
fig, axs = plt.subplots(nrows=size//N+1, sharey=True, figsize=(14,18), dpi=50)

fig.suptitle('Graph', 
          **{'family': 'Arial Black', 'size': 22, 'weight': 'bold'})

for ax, names, values in zip(axs, sublists_names, sublists_values):
    ax.bar(range(len(values)), values, align='center')
    ax.set_xlabel('X-Axis')
    ax.set_ylabel('Y-Axis')
    ax.set_xticks(range(len(names)))
    ax.set_xticklabels(names, rotation='vertical')
    ax.set_xlim(0, len(names))
    #ax.set_xlim(0, N)

fig.subplots_adjust(bottom=0.05, top=0.95)
plt.show()

enter image description here

If the list are not dividible by N, you can uncomment the last commented line so the bars stay alined on the last subplot : (ax.set_xlim(0, N)) :

enter image description here

Upvotes: 2

Related Questions