diff --git a/README.md b/README.md
index e138e76..7c46537 100644
--- a/README.md
+++ b/README.md
@@ -9,9 +9,9 @@ handle the same use-case. I have tried a couple of them, as well as the
 integrated CSV import of hledger, and ran into issues with all of them. That's
 why I wrote yet another CSV to ledger tool.
 
-There are two scripts, getofx, and toldg. The former uses the Python
+There are two main scripts, getofx, and toldg. The former uses the Python
 [ofxtools](https://ofxtools.readthedocs.io/en/latest/) library to download bank
-transactions via OFX and stores them into CSV files.  The latter takes CSV files
+transactions via OFX and stores them into CSV files. The latter takes CSV files
 and transforms them into ledger accounting files.
 
 The OFX script works well for my workflow, but I am not sure if it would be
@@ -31,6 +31,12 @@ my workflows are editor based, and the mapping file-based approach makes it easy
 to manipulate transactions. Also, the script relies on a single configuration
 file, which makes the configuration clearer.
 
+The directory `tools` contains additional scripts for personal use. Currently
+their main use-case is to generate a PDF report with figures. I use hledger to
+generate CSV data, plot figures with pandas, and then generate a report with
+pandoc. A shell script executes this process. This workflow fulfills my
+requirements, but is currently not useful for anybody else.
+
 ## Dependencies
 
 The scripts rely on a couple of newer Python features, such as data-classes,
@@ -84,4 +90,5 @@ getting warnings.
 - [x] Use OFX parser from ofxtools instead of parsing the XML
 - [x] Autoappend latest OFX data to CSV file
 - [x] Include example workspace with mock data to demo my workflow
+- [x] Write script to generate PDF reports
 
diff --git a/report.py b/report.py
deleted file mode 100644
index 0100a37..0000000
--- a/report.py
+++ /dev/null
@@ -1,32 +0,0 @@
-import subprocess
-import numpy as np
-import matplotlib.pyplot as plt
-import pandas as pd
-
-def configure_plot():
-    plt.figure()
-    axes = plt.gca()
-    axes.set_xlim([0, 300])
-    axes.set_ylim([-256, 100])
-    plt.xlabel("#bets []")
-    plt.ylabel("win [$]")
-
-def report():
-    df = pd.read_csv("report.csv",
-                     index_col='Account',
-                     parse_dates=True) 
-    df = df.drop(columns="Total:")
-    #print(df)
-    # print(df.info())
-    df.plot.bar()
-    plt.savefig('figure_1.png')
-    # plt.show()
-
-
-if __name__ == "__main__":
-    c = "hledger balance -M -V -b 2020 --depth 2 ^expenses: --transpose -o report.csv".split()
-    subprocess.call(c)
-    c = r"sed -i s/\$//g report.csv".split()
-    subprocess.call(c)
-    report()
-
diff --git a/tools/report.sh b/tools/report.sh
new file mode 100644
index 0000000..66d961f
--- /dev/null
+++ b/tools/report.sh
@@ -0,0 +1,48 @@
+#!/bin/sh
+
+CSV_FILE="data.csv"
+REPORT_MD="report.md"
+REPORT_PDF="/home/felixm/report.pdf"
+YEAR="2018-04"
+HLEDGER="hledger balance -M -V -b $YEAR --depth 1 --transpose -o $CSV_FILE"
+
+# Networth
+$HLEDGER -H '^assets'
+sed -i 's/\$//g' $CSV_FILE
+python tofig.py $CSV_FILE "figure_1.png"
+
+$HLEDGER '^assets'
+sed -i 's/\$//g' $CSV_FILE
+sed -i 's/assets/cashflow/g' $CSV_FILE
+python tofig.py $CSV_FILE "figure_2.png" --type bar
+
+$HLEDGER '^expenses'
+sed -i 's/\$//g' $CSV_FILE
+python tofig.py $CSV_FILE "figure_3.png" --type bar
+
+$HLEDGER '^income'
+sed -i 's/\$-//g' $CSV_FILE
+python tofig.py $CSV_FILE "figure_4.png" --type bar
+
+rm $CSV_FILE
+
+cat > $REPORT_MD <<- EOM
+# Financial Report
+
+# Networth
+![](figure_1.png)
+
+# Cashflow
+![](figure_2.png)
+
+# Expenses
+![](figure_3.png)
+
+# Income
+![](figure_4.png)
+EOM
+
+pandoc $REPORT_MD -o $REPORT_PDF
+rm figure_*
+rm $REPORT_MD
+
diff --git a/tools/tofig.py b/tools/tofig.py
new file mode 100644
index 0000000..2b2b85b
--- /dev/null
+++ b/tools/tofig.py
@@ -0,0 +1,40 @@
+import matplotlib.pyplot as plt
+import pandas as pd
+import argparse
+
+
+def line_format(label):
+    """
+    Convert time label to the format of pandas line plot
+    """
+    month = label.month_name()[:3]
+    if month == 'Jan':
+        month = f'{label.year}\n{month}'
+    return month
+
+
+def create_figure(args):
+    df = pd.read_csv(args.csv_file, index_col='Account', parse_dates=True)
+    df = df.drop(columns="Total:")
+    figsize=(10, 6)
+    if args.type == 'bar':
+        ax = df.plot(grid=True, kind='bar', figsize=figsize)
+        ax.set_xticklabels(map(lambda x: line_format(x), df.index))
+    else:
+        ax = df.plot(grid=True, figsize=figsize)
+    plt.savefig(args.png_file)
+    # plt.show()
+
+
+def get_args():
+    parser = argparse.ArgumentParser(description='Transform a CSV file into a bar chart.')
+    parser.add_argument('csv_file', type=str, help='CSV data file')
+    parser.add_argument('png_file', type=str, help='Chart png file')
+    parser.add_argument('--type', default='', type=str, help='Chart png file')
+    return parser.parse_args()
+
+
+if __name__ == "__main__":
+    args = get_args()
+    create_figure(args)
+