matplotlib:如何用文本定义行并标记行关节?

时间:2016-03-16 09:41:15

标签: python matplotlib

我正在尝试重新创建以下内容:

The wanted effects

任何意见将不胜感激。我想模仿这张照片,但我有3个问题:

  1. 如何知道两条线的关节和一条线的转折点?这些具体点能否从分析计算中计算出来?或matplotlib可以找出它们吗?

  2. 如何在线关节正下方绘制虚线垂直线段?

  3. 如何将文字粘贴到线段? matplotlib可以确定写入附加到行的文本的方便位置吗?或者我应该自己确定位置?

  4. 例如,我只能画下面的这种,远远少于要求。请帮我改进一下。

    我自己的照片,需要改进:

    My own picture

    到目前为止

    代码,详细代码如下:

    # -*- coding: utf-8 -*
    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib as mpl
    import math
    from pylab import *
    
    c = 2.998*10**10
    hp = 6.626*10**-27
    hb = 1.055*10**-27
    kb = 1.381*10**-16
    g = 6.673*10**-8
    me = 9.109*10**-28
    mp = 1.673*10**-24
    q = 4.803*10**-10 
    sigT = 6.652*10**-25
    p = 2.5
    E52 = 1000
    epsB_r = 0.01
    epse_r = 0.1
    
    D28 = 1 
    n1 = 1.0
    
    nu15 = 2*10**(-3)
    r014 = 1
    g42 = 5
    delt12 =1
    g4 = g42*10**2
    
    E0 = E52*10**52
    eta = g4
    N0 = E0/(g4*mp*c**2)
    
    p_td = 24*3600
    p_txd = 3**(1./3)*2**(-4./3)*10**(52./3)*pi**(-1./3)*mp**(-1./3)*c**(-5./3)/p_td 
    txd = p_txd*n1**(-1./3)*eta**(-8./3)*E52**(1./3) 
    
    p_Fmax_r1 = 2**(1./2)*3**(-1)*pi**(-1./2)*me*mp**(1./2)*c**3*sigT*q**(-1)*p_txd**(-3./2)*10**(-56)
    Fmax_r1 = lambda t : p_Fmax_r1*N0*eta**6*E52**(-1./2)*n1*epsB_r**(1./2)*D28**(-2)*t**(3./2)
    p_Fmax_r2 = 2**(1./2)*3**(-1)*pi**(-1./2)*me*mp**(1./2)*c**3*sigT*q**(-1)*p_txd**(34./35)*10**(-56)
    Fmax_r2 = lambda t : p_Fmax_r2*N0*epsB_r**(1./2)*D28**(-2)*t**(-34./35)*eta**(-62./105)*n1**(37./210)*E52**(34./105)
    
    p_nuc_r1 = 2**(-13./2)*3**2*me*mp**(-3./2)*c**(-2)*sigT**(-2)*pi**(-1./2)*q*p_td**(-2)
    p_nuc_r2 = 2**(-13./2)*3**2*pi**(-1./2)*me*mp**(-3./2)*c**(-2)*sigT**(-2)*q*p_txd**(-74./35)*p_td**(-2)
    nuc_r1 = lambda t : p_nuc_r1*eta**(-4)*epsB_r**(-3./2)*n1**(-3./2)*t**(-2)
    nuc_r2 = lambda t : p_nuc_r2*eta**(172./105)*t**(4./35)*n1**(-167./210)*epsB_r**(-3./2)*E52**(-74./105)
    
    p_num_r1 = 2**(11./2)*7**(-2)*mp**(5./2)*me**(-3)*pi**(-1./2)*q*p_txd**(-6)
    p_num_r2 = 2**(11./2)*7**(-2)*mp**(5./2)*me**(-3)*pi**(-1./2)*q*p_txd**(54./35)
    
    num_r1 = lambda t : p_num_r1*eta**18*((p-2)/(p-1))**2*epse_r**2*epsB_r**(1./2)*n1**(5./2)*t**6*E52**(-2)
    num_r2 = lambda t : p_num_r2*((p-2)/(p-1))**2*n1**(-1./70)*eta**(-74./35)*E52**(18./35)*t**(-54./35)*epse_r**2*epsB_r**(1./2)
    
    def num_r_(t):
         return num_r1(t) if t<txd else num_r2(t)
    num_r = np.vectorize(num_r_)
    def nuc_r_(t):
         return nuc_r1(t) if t<txd else nuc_r2(t)
    nuc_r = np.vectorize(nuc_r_)
    def Fmax_r_(t):
         return Fmax_r1(t) if t<txd else Fmax_r2(t)
    Fmax_r = np.vectorize(Fmax_r_)
    
    i= np.arange(-5,-2,0.05)
    t = 10**i
    dnum   = [math.log10(mmm) for mmm in num_r(t)]
    dnuc   = [math.log10(j) for j in nuc_r(t)]
    nu_obs = [math.log(nu15*10**15,10) for a in i]
    plt.figure('God Bless: Observable Limit')
    plt.title(r'$\nu_{obs}$ and $\nu_c$ and $\nu_m$''\nComparation')
    plt.xlabel('Time: log t')
    plt.ylabel(r'log $\nu$')
    plt.axvline(math.log10(txd))
    plt.plot(i,nu_obs,'--',linewidth=2,label=r'$\nu_{obs}$')
    plt.plot(i,dnum,'-.',linewidth=2,label=r'$\nu_m$')
    plt.plot(i,dnuc,linewidth=2,label=r'$\nu_c$')
    plt.savefig("test4.eps", dpi=120,bbox_inches='tight')
    plt.legend()
    
    plt.show()
    

1 个答案:

答案 0 :(得分:0)

我只是找到一个解决方案,不确定是否会有更好的解决方案。

我在这里参考了:Annotate some points

我假设这样的解决方案:

1,我们可以计算线的联合点协调。  2,如果我们想绘制垂直线的一段,即连接点下方的线段,我们可以选择两个点来绘制一条短线。这确实有效!  3,也许我们只能找到说明文字的位置,并将文字附在那个地方。

我添加了这样的短语:

plot([math.log10(txd),math.log10(txd)],[4,math.log10(nuc_r(txd))], color ='blue', linewidth=2.5, linestyle="--")
scatter([math.log10(txd),],[math.log10(nuc_r(txd))], 50, color ='blue')

annotate(r'$sin(\frac{2\pi}{3})=\frac{\sqrt{3}}{2}$',
     xy=(math.log10(txd), math.log10(nuc_r(txd))), xycoords='data',
     xytext=(+10, +30), textcoords='offset points', fontsize=16,
     arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))

结果如下: A Better One