diff --git a/src/main/java/de/deadlocker8/budgetmaster/charts/DefaultCharts.java b/src/main/java/de/deadlocker8/budgetmaster/charts/DefaultCharts.java
index 44424b926a84d2058a82f3b6756cd129a3484059..684c1862f6ee5924d9141178cd8b61dccdd410ff 100644
--- a/src/main/java/de/deadlocker8/budgetmaster/charts/DefaultCharts.java
+++ b/src/main/java/de/deadlocker8/budgetmaster/charts/DefaultCharts.java
@@ -23,15 +23,19 @@ public class DefaultCharts
 
 	private static final Chart CHART_INCOMES_AND_EXPENDITURES_PER_MONTH_BAR = new Chart("charts.default.incomesAndExpendituresPerMonthBar",
 			getChartFromFile("charts/IncomesAndExpendituresPerMonthBar.js"),
-			ChartType.DEFAULT, 2);
+			ChartType.DEFAULT, 3);
 
 	private static final Chart CHART_INCOMES_AND_EXPENDITURES_PER_MONTH_LINE = new Chart("charts.default.incomesAndExpendituresPerMonthLine",
 			getChartFromFile("charts/IncomesAndExpendituresPerMonthLine.js"),
-			ChartType.DEFAULT, 2);
+			ChartType.DEFAULT, 3);
 
 	private static final Chart CHART_INCOMES_AND_EXPENDITURES_BY_CATEGORY_BAR = new Chart("charts.default.incomesAndExpendituresByCategoryBar",
 			getChartFromFile("charts/IncomesAndExpendituresByCategoryBar.js"),
-			ChartType.DEFAULT, 11);
+			ChartType.DEFAULT, 12);
+
+	private static final Chart CHART_INCOMES_AND_EXPENDITURES_PER_MONTH_BY_CATEGORIES = new Chart("charts.default.incomesAndExpendituresPerMonthByCategories",
+		getChartFromFile("charts/IncomesAndExpendituresPerMonthByCategories.js"),
+		ChartType.DEFAULT, 3);
 
 
 	public static List<Chart> getDefaultCharts()
@@ -41,6 +45,7 @@ public class DefaultCharts
 		charts.add(CHART_INCOMES_AND_EXPENDITURES_PER_MONTH_BAR);
 		charts.add(CHART_INCOMES_AND_EXPENDITURES_PER_MONTH_LINE);
 		charts.add(CHART_INCOMES_AND_EXPENDITURES_BY_CATEGORY_BAR);
+		charts.add(CHART_INCOMES_AND_EXPENDITURES_PER_MONTH_BY_CATEGORIES);
 
 		charts.sort(Comparator.comparing(Chart::getName));
 		return charts;
diff --git a/src/main/resources/charts/IncomesAndExpendituresPerMonthByCategories.js b/src/main/resources/charts/IncomesAndExpendituresPerMonthByCategories.js
new file mode 100644
index 0000000000000000000000000000000000000000..0e0066378aa42e70616303f264518ea1223de74c
--- /dev/null
+++ b/src/main/resources/charts/IncomesAndExpendituresPerMonthByCategories.js
@@ -0,0 +1,166 @@
+/* This list will be dynamically filled with all the transactions between
+ * the start and and date you select on the "Show Chart" page
+ * and filtered according to your specified filter.
+ * An example entry for this list and tutorial about how to create custom charts ca be found in the BudgetMaster wiki:
+ * https://github.com/deadlocker8/BudgetMaster/wiki/How-to-create-custom-charts
+ */
+var transactionData = [];
+
+// Note: All variables starting with "localized" are only available inside default charts.
+
+transactionData = transactionData.reverse();
+
+moment.locale('de');
+
+
+const NAME = 0;
+const COLOR = 1;
+const INCOME = 2;
+const EXPENDITURE = 3;
+
+var dates = [];
+var values = [];
+
+for(var i = 0; i < transactionData.length; i++)
+{
+    var transaction = transactionData[i];
+
+    var date = moment(transaction.date).startOf('month').format('MMM YY');
+    if(!dates.includes(date))
+    {
+        dates.push(date);
+        values.push([
+            [], [], [], []  // NAME, COLOR, INCOME, EXPENDITURE
+        ]);
+    }
+
+    // determine index of category name in list
+    var lastIndex = values.length - 1;
+
+    var categoryName = transaction.category.name;
+    // create new category if not already in dict
+    if(!values[lastIndex][NAME].includes(categoryName))
+    {
+        values[lastIndex][NAME].push(categoryName);
+        values[lastIndex][COLOR].push(transaction.category.color);
+        values[lastIndex][INCOME].push(0);
+        values[lastIndex][EXPENDITURE].push(0);
+    }
+
+    // determine index of category in current last values
+    var index = values[lastIndex][NAME].indexOf(categoryName);
+
+    // add to income or expenditure sum
+    var amount = transaction.amount;
+    if(amount > 0)
+    {
+        values[lastIndex][INCOME][index] = values[lastIndex][INCOME][index] + amount;
+    }
+    else
+    {
+        values[lastIndex][EXPENDITURE][index] = values[lastIndex][EXPENDITURE][index] + Math.abs(amount);
+    }
+}
+
+var totalIncomeSums = [];
+var totalExpenditureSums = [];
+
+// calculate total sums for all months
+for(var i = 0; i < dates.length; i++)
+{
+    var totalIncomes = 0;
+    var totalExpenditures = 0;
+
+    values[i][INCOME].forEach(function(value)
+    {
+        totalIncomes += value;
+    });
+
+    values[i][EXPENDITURE].forEach(function(value)
+    {
+        totalExpenditures += value;
+    });
+
+    totalIncomeSums.push(totalIncomes);
+    totalExpenditureSums.push(totalExpenditures);
+}
+
+// Prepare your chart settings here (mandatory)
+var plotlyData = [];
+var plotlyLayout = {
+    title: {
+        text: localizedTitle
+    },
+    barmode: "stack",
+    hovermode: 'closest', // show hover popup only for hovered item
+    yaxis: {
+        rangemode: 'tozero',
+        tickformat: '.2f %',
+        showline: true
+    }
+};
+
+// create one stacked bar for incomes and one for expenditures for every month and group them by month
+for(var i = 0; i < dates.length; i++)
+{
+    for(var j = 0; j < values[i][NAME].length; j++)
+    {
+        var currentValues = values[i];
+
+        var percentageIncome = (100 / totalIncomeSums[i]) * currentValues[INCOME][j];
+        var textIncome = prepareHoverText(percentageIncome, currentValues[INCOME][j]);
+
+        var percentageExpenditure = (100 / totalExpenditureSums[i]) * currentValues[EXPENDITURE][j];
+        var textExpenditure = prepareHoverText(percentageExpenditure, currentValues[EXPENDITURE][j]);
+
+        plotlyData.push({
+            x: [localizedData['label2'], localizedData['label1']],
+            y: [percentageIncome, percentageExpenditure],
+            type: 'bar',
+            hoverinfo: 'text',
+            text: [textIncome, textExpenditure],
+            name: currentValues[NAME][j],
+            xaxis: 'x' + (i + 1),  // for grouping incomes and expenditure bar by month
+            barmode: 'stack',
+            marker: {
+                color: currentValues[COLOR][j]  // use the category's color
+            }
+        });
+    }
+
+    // axis number inside layout uses a different counting in comparison to xaxis definition in plotlyDate
+    var axisNumber = i + 1;
+    if(i === 0)
+    {
+        axisNumber = '';
+    }
+
+    // calculate subplot start and end position (relative between 0 and 1)
+    var width = 1 / dates.length;
+    var start = i * width;
+    var end = (i + 1) * width;
+
+    plotlyLayout['xaxis' + axisNumber] = {
+        domain: [start, end],
+        anchor: 'x' + axisNumber,
+        title: dates[i],
+    }
+}
+
+// Add your Plotly configuration settings here (optional)
+var plotlyConfig = {
+    showSendToCloud: false,
+    displaylogo: false,
+    showLink: false,
+    responsive: true
+};
+
+// Don't touch this line
+Plotly.newPlot('chart-canvas', plotlyData, plotlyLayout, plotlyConfig);
+
+
+function prepareHoverText(percentage, value)
+{
+    value = value / 100;
+    return percentage.toFixed(1) + '% (' + value.toFixed(1) + ' ' + localizedCurrency + ')';
+}
\ No newline at end of file
diff --git a/src/main/resources/languages/_de.properties b/src/main/resources/languages/_de.properties
index edec359bdae79ddfa7b2f0be9d513656d4dae0b3..c0cfad504a94ad05ee77a9197c190bc823de12a0 100644
--- a/src/main/resources/languages/_de.properties
+++ b/src/main/resources/languages/_de.properties
@@ -337,6 +337,8 @@ charts.default.incomesAndExpendituresPerMonthLine=Eingaben/Ausgaben pro Monat (L
 charts.default.incomesAndExpendituresPerMonthLine.localization='{"axisY": "Summe in ", "traceName1": "Einnahmen", "traceName2": "Ausgaben"'}
 charts.default.incomesAndExpendituresByCategoryBar=Eingaben/Ausgaben nach Kategorien
 charts.default.incomesAndExpendituresByCategoryBar.localization='{"label1": "Ausgaben", "label2": "Einnahmen"'}
+charts.default.incomesAndExpendituresPerMonthByCategories=Eingaben/Ausgaben pro Monat (nach Kategorien)
+charts.default.incomesAndExpendituresPerMonthByCategories.localization='{"label1": "Ausgaben", "label2": "Einnahmen"'}
 charts.default.categoryBudget=Verbrauch nach Kategorien
 
 chart.new.label.name=Name
diff --git a/src/main/resources/languages/_en.properties b/src/main/resources/languages/_en.properties
index a35b9dbd6471ce7df957eff499e53b90b1bbe42f..9eb4f0c8e478949007f3ff6a35a9f2b64bd90f84 100644
--- a/src/main/resources/languages/_en.properties
+++ b/src/main/resources/languages/_en.properties
@@ -337,6 +337,8 @@ charts.default.incomesAndExpendituresPerMonthLine=Incomes/Expenditures per month
 charts.default.incomesAndExpendituresPerMonthLine.localization='{"axisY": "Sum in ", "traceName1": "Incomes", "traceName2": "Expenditures"'}
 charts.default.incomesAndExpendituresByCategoryBar=Incomes/Expenditures by categories
 charts.default.incomesAndExpendituresByCategoryBar.localization='{"label1": "Expenditures", "label2": "Incomes"'}
+charts.default.incomesAndExpendituresPerMonthByCategories=Incomes/Expenditures per month (By categories)
+charts.default.incomesAndExpendituresPerMonthByCategories.localization='{"label1": "Expenditures", "label2": "Incomes"'}
 charts.default.categoryBudget=Consumption by categories
 
 chart.new.label.name=Name