如何在matplotlib中的每个xtick旁边显示计算值?

时间:2017-03-08 01:54:04

标签: python matplotlib

如果我给代码一个原始的'工作的价值我希望每个x-tick显示该值的百分比变化。

I.E如果我将10设置为原始值,我希望网格线为5,读取为5(-50%),20为20(+100%)

括号中的术语颜色将是额外的奖励。

编辑:源代码

所以这是代码。它已被改变了很多次以填补某个角色,所以它不是最好的,但你明白了。它只是一个交易的p / l计算器,它考虑了佣金和股息支付。

我希望图表的中心是"当前股价"和图表中任意一侧的股票价格显示当前股票价格的百分比变化'

from colorama import Fore, Style
import numpy as np 
import matplotlib.pyplot as plt 
from matplotlib.widgets import Cursor


name='XYZ'
current_stock_price=8.66

closing_price=current_stock_price       #price at which you close the position

#first trade 
entrance_price1=9.55
number_shares1=1500
dividend1=0.0
longshort1='short'   #is it a long or short position? 

#second trade 
entrance_price2=8.93
number_shares2=1200
dividend2=0.0
longshort2='short' 

def commission_stock(commission_rate, cost, commission_minimum,     number_shares): 

    com=commission_rate/100*cost
    #com=commission_rate*number_shares

    if com<commission_minimum:
        com=commission_minimum

    return com 

def pl_calculator(entrance_price, closing_price, number_shares, \
              commission_shares, commission_minimum, dividend_amount, name,\
              longshort): 

    name=name
    longshort=longshort

    entrance_price= entrance_price
    closing_price= closing_price

    stock_change=closing_price-entrance_price #change in stock price

    number_shares=number_shares

    commission_shares=commission_shares#percent or per/number of shares
    commission_minimum=commission_minimum

    dividend_amount=dividend_amount   #dollars per share 
    dividend_cost=dividend_amount*number_shares #how much you pay in dividends

    margin_req=1

    nominal_value=number_shares*entrance_price #value of shares (not   necessarily   how much we own if margin is involved) 
    cost_to_exit_share=number_shares*closing_price

    outlay=nominal_value*margin_req #amount of money required up front 

    movement=float(closing_price)/entrance_price*100-100 #stock price movement

    stock_pl=number_shares*(closing_price-entrance_price) #numerical value of profit or loss 

    commission_shares_enter=commission_stock(commission_shares, nominal_value, commission_minimum, number_shares)
    commission_shares_exit=commission_stock(commission_shares, cost_to_exit_share,    commission_minimum, number_shares)
    commission=commission_shares_enter+commission_shares_exit

    if longshort=='long':
        stock_pl=stock_pl-commission_shares_enter-      commission_shares_exit+dividend_cost
    elif longshort=='short': 
        stock_pl=-stock_pl-commission_shares_enter-commission_shares_exit-dividend_cost
    else: 
        raise AttributeError 

    pl_perc=stock_pl/nominal_value*100 
    pl_perc_outlay=stock_pl/outlay*100 #profit or loss on outlaid cash. If margin=1 then pl_perc_outlay=pl_perc

    return [stock_pl, pl_perc, commission, dividend_cost]


def print_graph(current_stock_price, profit_current, profit_chosen, closing_price, name):

#creates a list of stock prices either side of current stock price and substitutes each of these into the p/l calculator to give the rough idea of a p/l graph. 

    fig=plt.figure()
    ax=fig.add_subplot(111)

    a=float(current_stock_price)*0.6
    b=float(current_stock_price)*1.4


    #create list of the stockprices to be tested 
    data=np.arange(a, b, 0.25)

    #create empty list to populate with theh profit value at each point
    profit_points=np.zeros(len(data), dtype='f') 

    i=0

    while i <= (len(data)-1): 

        profit1=pl_calculator(entrance_price=entrance_price1, closing_price=data[i], number_shares=number_shares1,\
                commission_shares=0.1, commission_minimum=8, dividend_amount=dividend1,\
                name=name, longshort=longshort1)

        profit2=pl_calculator(entrance_price=entrance_price2, closing_price=data[i], number_shares=number_shares2,\
                commission_shares=0.1, commission_minimum=8, dividend_amount=dividend2,\
                name=name, longshort=longshort2)


        #append the profit at this particular price to a list
        profit_points[i]=profit1[0]+profit2[0]



        i+=1 

    ax.plot(data, profit_points) 
    ax.plot(current_stock_price, profit_current, 'ro', label='Current Position')                
    ax.plot(closing_price, profit_chosen, 'g^', label='Chosen Closing Position') 

    cursor = Cursor(ax, useblit=True, color='k', linewidth=1)   

    ax.grid(axis='both')


    plt.xlabel('%s($)' %name)
    plt.ylabel('P/L ($)') 
    plt.title('P/L') 
    plt.legend(loc='upper right', numpoints=1)

    plt.show() 







#run cases for current stock price and chosen stock price 
trade1_current=pl_calculator(entrance_price=entrance_price1,     closing_price=current_stock_price, number_shares=number_shares1,\
                commission_shares=0.1, commission_minimum=8,    dividend_amount=dividend1,\
                name=name, longshort=longshort1) 

trade2_current=pl_calculator(entrance_price=entrance_price2,    closing_price=current_stock_price, number_shares=number_shares2,\
                commission_shares=0.1, commission_minimum=8,   dividend_amount=dividend2,\
                name=name, longshort=longshort2)

trade1_chosen=pl_calculator(entrance_price=entrance_price1,   closing_price=closing_price, number_shares=number_shares1,\
                commission_shares=0.1, commission_minimum=8,   dividend_amount=dividend1,\
                name=name, longshort=longshort1) 

trade2_chosen=pl_calculator(entrance_price=entrance_price2,   closing_price=closing_price, number_shares=number_shares2,\
                commission_shares=0.1, commission_minimum=8,   dividend_amount=dividend2,\
                name=name, longshort=longshort2)





profit_current=trade1_current[0]+trade2_current[0]
profit_chosen=trade1_chosen[0]+trade2_chosen[0]

dividend=trade1_current[3]+trade2_current[3]

movement=closing_price/current_stock_price*100-100

print '%s: $%.2f' %(name, current_stock_price)
print '@ $%.2f (%.2f%%)' %(closing_price, movement)
print 'Dividend Payment: $%.2f' %dividend
print 'Profit: $%.2f'%(trade1_current[0]+trade2_current[0])


print_graph(current_stock_price, profit_current, profit_chosen, closing_price, name) 

2 个答案:

答案 0 :(得分:0)

您可以继承matplotlib.ticker.ScalarFormatter以添加百分比编号,如下所示:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker

class MyPercentageFormatter(matplotlib.ticker.ScalarFormatter):
    def __init__(self,origval, offset=False, mathText=True):
        self.origval = float(origval)
        matplotlib.ticker.ScalarFormatter.__init__(self,useOffset=offset,useMathText=mathText)
    def pprint_val(self, x):
        val = matplotlib.ticker.ScalarFormatter.pprint_val(self, x)
        perc = x/self.origval*100
        newval = val + "({perc:.0f}%)".format(perc=perc)
        return newval


x = np.arange(50)
y = np.sin(x/10.)

fig, ax = plt.subplots()
ax.xaxis.set_major_formatter(MyPercentageFormatter(20))
ax.plot(x,y)

plt.show()

enter image description here

答案 1 :(得分:0)

您需要使用自定义Formatter类来执行此操作。我会为你的特定情况推荐像FuncFormatter这样的东西,因为你依赖的是外部&#34;原创&#34;值。你可以做点什么

from matplotlib.ticker import FuncFormatter
ax.xaxis.set_major_formatter(FuncFormatter(lambda x, pos: '{}({:d}%)'.format(x, int(x / original * 100.0 + 0.5))))

使用LaTeX可以部分实现颜色,但前提是您使用支持这种渲染的支持。你也可以在轴上创建自己的标签并移动它们来模拟刻度线,但我怀疑这对于有限的收益来说太过分了。相关帖子位于:Partial coloring of text in matplotlib

轻微的挑剔,考虑使用fig, ax = plt.subplots()而不是两行。