So my input data is two dictionary D1 and D2, it looks like this:
D1 = {
'A':{'X1':1, 'X2':2},
'B':{'X3':3, 'X4':4,'X5':10},
...
'T':{'X100':30}
}
D2 = {
'A':{'X1':4, 'X2':2},
'B':{'X3':13, 'X4':2,'X5':8},
...
'T':{'X100':16}
}
UPDATE: I manually draw a picture to show what I want here.
Both D1 and D2 has 20 keys (from A to T, let's call these main keys), and each main key corresponds to another dictionary with the same keys, for example, A corresponds to another dictionary with key X1 and X2 (let's call these X keys since they all start with X). I want to draw a 4 by 5 barcharts in one plot, each barchart corresponds to one main key. For each individual plot, I want to plot a barchart with categories correspond to X keys.
Now I ran into two issues, any help on the two issues will be much appreciated.
First issue is as you can see # of X keys are different in each category, how do I create dynamic bars in barchart based on # of X keys? One way I can think of is create variable based on X key names.
Second issue is how do I group these 20 dynamic barcharts in a single plot? Thanks a lot in advance!
CodePudding user response:
You can convert the dictionaries to a long form dataframe. And then use seaborn's sns.catplot()
to draw a grid of bar plots:
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
import pandas as pd
# first, create some test data with the given structure
mains = [*'ABCDEFGHIJKLMNOPQRST']
lengths = np.random.randint(2, 11, len(mains))
starts = np.append(0, lengths.cumsum())
D1 = {main: {f'X{i}': np.random.randint(2, 10) for i in range(s0, s1)}
for main, s0, s1 in zip(mains, starts[:-1], starts[1:])}
D2 = {main: {f'X{i}': np.random.randint(2, 10) for i in range(s0, s1)}
for main, s0, s1 in zip(mains, starts[:-1], starts[1:])}
# create a "long form" dataframe of the given dictionaries
df = pd.concat([pd.DataFrame({'Dictionary': ['D1'], 'main': [main], 'x': [x], 'Height': [val]})
for main in D1.keys() for x, val in D1[main].items()]
[pd.DataFrame({'Dictionary': ['D2'], 'main': [main], 'x': [x], 'Height': [val]})
for main in D2.keys() for x, val in D2[main].items()], ignore_index=True)
# draw a grid of barplots
g = sns.catplot(kind='bar', data=df, x='x', y='Height', hue='Dictionary', palette='spring',
col='main', col_wrap=5, height=3, aspect=1.5, sharex=False)
g.set(xlabel='') # remove superfluous x labels
plt.show()