Recently, I am studying engineering economics, and I often have to draw cash flow diagrams. Wish it was easier to draw cash flow diagrams in Python. Although I don’t know if this makes sense.
1. Draw a cash flow diagram based on the cash flow statement
Suppose you have the following cash flow statement:
project – year t |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
invest |
600 |
||||||
income |
350 |
350 |
450 |
450 |
450 |
450 |
|
Operating costs |
200 |
200 |
250 |
250 |
250 |
250 |
It is desirable to draw a corresponding advanced flow diagram based on this cash flow statement.
code show as below:
""" Draw a Flow of Funds Diagram """ "Color Settings" arrow_color = 'black' axis_color = 'black' title_color = 'black' 'Import the corresponding library' import matplotlib.pyplot as plt import numpy as np ' Set the plot title ' plt.title("Cash Flow Diagram", c=title_color) plt.ylabel("Fund (ten thousand)") ' set initial variable value ' # Dispersion of chart elements # It is convenient to adjust the chart distribution when the value changes distance=50 # Use a second-order list to save the value of the cash flow A = [[ -600, 0, 0, 0, 0, 0, 0 ] , [ 0, 350, 350, 450, 450, 450, 450 ], [ 0, -200, -200, -250, -250, -250, -250 ] ] 'Draw a flow of money graph from a list' # Distinguish between positive and negative values # It is to make the label position of negative value lower and not affect the look and feel for j in range(0,len(A)): for i in range(0,len(A[j])): if A[j][i] > 0: plt.arrow(i, 0, 0, A[j][i]-distance, fc=arrow_color, ec=arrow_color, shape="full", head_width=0.1, head_length=distance, overhang=0.5) plt.text(i + len(A)*0.01, A[j][i] + distance, str(round(A[j][i],2))) elif A[j][i] < 0: plt.arrow(i, 0, 0, A[j][i]-distance, fc=arrow_color, ec=arrow_color, shape="full", head_width=0.1, head_length=distance, overhang=0.5) plt.text(i + len(A)*0.01, A[j][i]-distance, str(round(A[j][i],2))) ' Set the characteristics of individual elements in the diagram ' # The following are actually nothing, mainly to beautify the chart ax = plt.gca() # Set the four coordinate axes to be invisible ax.spines['top'].set_visible(False) # set the coordinate axis, the same below ax.spines['right'].set_visible(False) ax.spines['left'].set_visible(False) ax.spines['bottom'].set_visible(False) # Move the x-axis and its data labels into the chart ax.spines['bottom'].set_position(('data',0)) plt.setp( ax.xaxis.get_majorticklabels(), ha="left" ) # right indicates that the X coordinate data labels are aligned to the right plt.arrow(-0.1, 0, len(A[0]) + 1.2, 0, fc=axis_color, ec=axis_color, shape="full", head_width=distance*0.5, head_length=0.3, overhang=0.5 ) # hide the y coordinate plt. yticks ([]) # Set the scale of the x-axis to 1 x_major_locator=plt.MultipleLocator(1) # Set the scale interval of the x-axis to 1 and store it in the variable ax.xaxis.set_major_locator(x_major_locator) # Set the main scale of the x-axis to a multiple of 1 # Set the X Y range of the chart to prevent the drawing area from being too large or too small plt.xlim(-0.1, len(A[0]) + 1.4) plt.ylim(-15*distance, 15*distance) 'Adjust Chinese display ' plt.rcParams['font.sans-serif'] = ['SimHei'] # used to display Chinese labels normally plt.rcParams['axes.unicode_minus'] = False # used to display the negative sign normally 'drawing' plt. show()
Drawing effect:
2. Draw cash flow diagrams of equal amounts, equal differences, and equal ratio sequences
For the drawing of equal amount, equal difference, and proportional sequence cash flow diagrams, you can use a loop similar to the following. You can use the loop to generate a proportional sequence and add it to the first line of list A, and draw a proportional curve at the same time.
A[0].append(-30) 'Generate a sequence of ratios' for i in range(0,7): A[0].append(10*(1.2)**i) # Draw a proportional curve x = np.arange(1,8) y = 10*(1.2**(x-1)) plt.plot(x,y, c='g', ls='--')
Drawing effect:
3. Combining various drawing methods to draw a more complex cash flow diagram
Design a more complex matrix:
# Use a second-order list to save the value of the cash flow A = [[ 0, 80000, 80000, 0 ] , [ -100000, -30000, -30000, 0 ] , [ 0, 0, 30000, 0 ] , [ 0, 0, -300000, -50000 ] , [ 0, 0, 0, 150000 ] , [ 0, 0, 0, 240000 ]
Set arrow_color to be a list, and change the part that iterates over the matrix to arrow_color[j] to set a different color for each row of the matrix.
"Color Settings" arrow_color = ['green','green','green','red','red','red'] axis_color = 'black' title_color = 'black'
for j in range(0,len(A)): for i in range(0,len(A[j])): if A[j][i] > 0: plt.arrow(i, 0, 0, A[j][i]-distance, fc=arrow_color[j], ec=arrow_color[j], shape="full", head_width=0.1, head_length=distance, overhang=0.5) plt.text(i + len(A)*0.01, A[j][i] + distance, str(round(A[j][i],2))) elif A[j][i] < 0: plt.arrow(i, 0, 0, A[j][i] + distance, fc=arrow_color[j], ec=arrow_color[j], shape="full", head_width=0.1, head_length=distance, overhang=0.5) plt.text(i + len(A)*0.01, A[j][i]-distance, str(round(A[j][i],2)))
Add labels to label the funding rate and legend.
# add some tags plt.text(0, 250000, r'interest rate $i_{c} = 10 %$') 'Add Legend' line1, = plt.plot(1,1, 'g', label='old equipment cash flow') line2, = plt.plot(2,2, 'r', label='new equipment cash flow') plt.legend(handles=[line1, line2], loc='lower right')
Drawing effect: