I am trying to plot a financial contribution analysis, one bar chart with two vertical bars, one representing a portfolio's gain contributed by equity and the other by Fixed Income (bonds)
over a certain time period.
%matplotlib inline
import numpy as np
import pandas as pd
import itertools
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import matplotlib.lines as mlines
import matplotlib.dates as mdates
import matplotlib.font_manager as fm
import matplotlib.patches as mpatches
import matplotlib.transforms as mtrans
d = {'col1': [0.006269, 0.003842, 0.002237, 0.001448, 0.000752, 0.000166]}
equity = pd.DataFrame(data=d, index=['Aktien Nordamerika', 'Gold', 'Aktien Flexibel', 'Aktien Europa', 'Aktien Schwellenlaender', 'Aktien Pazifik'])
d2 = {'col1': [0.009533, 0.003879, 0.001926, 0.000714]}
bonds = pd.DataFrame(data=d2, index=['Anleihen Investmentgrade', 'Hedgefonds', 'Hochzinsanleihen', 'Anleihen Schwellenlaender'])
The vertical bars starting at the x-axis should in sum represent the overall gain from ['equity','bonds‘]
but be divided into by the index defined in the df.
I tried to do that by using the iterator building block itertools.zip_longest
to assign the values of the incrementally gaining bar chart and then the color for each section.
fig, ax = plt.subplots()
fig.set_size_inches(4, 4.3)
bar_width = 0.26
x_values = np.array([0, 1.2])
x_pos = [list(x_values)]*2 + [x_values[0]]*4
pl = [(p1,p2) if p2 is not None else p1 for p1, p2 in itertools.zip_longest(list(equity['col1'].values), list(bonds['col1'].values))]
colors = np.array((
['#FF7600', '#A9A9A9', '#1778A6', '#146189', '#5794B9', '#B0D2E7'],
['#004232', '#3AC2A0', '#007558', '#2A8C74']))
colormap = [(c1,c2) if c2 is not None else c1 for c1, c2 in itertools.zip_longest(colors[0],colors[1])]
then I would just use matplotlib's matplotlib.pyplot.bar(x, height, width=0.8, bottom=None, *, align='center', data=None, **kwargs)
to create the desired bar chart..
for x, p, c in zip(x_pos, pl, colormap):
ls_sub_aktien = plt.bar(x, p, align='edge', width=bar_width, linewidth=0.0001, color=c)
BUT the output does not give me the total division in the ['bonds']
bar, where only two of the row items are colored as defined...
The output I got with the missing 4 color split on the right bar:
Also, the left bar appears to include a color which should actually be found in the bar on the right hand side.
It would be amazing if you have had a similar issue and remember how you solved it, or if you have suggestion on how I could create this chart using a different approach. Sorry for my English and if anything is unclear let me know. Try it out, please. I'm wondering if you can solve it, thank you!