从文件中读取上标字符;并且无法更改绘图中的字体

时间:2019-03-01 02:09:46

标签: python matplotlib fonts

这是我要读取的数据文件:

# Magic number=03052015, 03 May 2015
# Single electron capture cross sections, nl state-selective
# Ne^9+ + H -> Ne^8+ + H^+
# Method=MCLZ
# Fname Lname et al. 2015, to be submitted
# ----------------------------------------------------------------------------
# Energy                Cross sections (10^-16 cm^2)
# (eV/u)        6g(¹G)          6h(¹H)          6f(¹F)          6d(¹D)          6p(¹P)          6s(¹S)          5g(¹G)          5f(¹F)          5d(¹D)          5p(¹P)          5s(¹S)          4f(¹F)          4d(¹D)          4p(¹P)          4s(¹S)          3d(¹D)          3p(¹P)          3s(¹S)          2p(¹P)          2s(¹S)          1s(¹S)          Total
1.000e-03       1.4776575e+02   1.7912626e+01   3.3462628e+02   1.9095364e+02   3.1276734e+01   6.2973301e+00   2.7468161e+00   2.3678743e-02   3.9230170e-09   8.1993422e-19   8.8673478e-24   1.5223718e-25   2.7018743e-34   4.8461238e-50   9.1037642e-59   1.4490583e-62   7.8949338e-74   3.7299268e-81   4.5993532e-83   5.4748211e-85   1.8820422e-85   7.3160285e+02
1.053e-03       1.4035132e+02   1.7013729e+01   3.1787085e+02   1.8143965e+02   2.9728031e+01   5.9865955e+00   2.6114108e+00   2.2513903e-02   3.7310299e-09   7.8009353e-19   8.4379868e-24   1.4486669e-25   2.5712078e-34   4.6122120e-50   8.6648019e-59   1.4192296e-62   7.7128879e-74   3.6383824e-81   4.3776881e-83   5.2109659e-85   1.8265794e-85   6.9502410e+02
...
...
...

我正在阅读以作图。我需要从最后一条注释行中获取该图的标签。我正在读取文件两次:一次获取注释,再一次获取实际数据。

由于扩展了ascii或unicode字符,我在注释行上遇到了麻烦。在这里研究答案,我实现了一些解决方案来读取行而不会崩溃。但是,不是读上标“ 1”。有时其上标为“ 2”或“ 3”。

在图例中得到的结果是:6g(G),6h(H)等。

这是我的全部脚本:

#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
This script was written to read a "cs" (cross section) file, which was generated by
"Stueckelberg", and plot it. It is intended to mimic the graphs produced by xmgrace.

$Id: plotcs.py,v 1.3 2019/02/27 02:08:30 micha Exp micha $
$Author: micha $
$Revision: 1.3 $
$Log: plotcs.py,v $
Revision 1.3  2019/02/27 02:08:30  micha
Added "-l" option to specify size of labels font.

Revision 1.2  2019/02/26 05:35:35  micha
Added ability to get label information from *.cs file. This data will be used for legends. Also included "-t" option to display title on plot. Title data is taken from *cs file in the header section.

Revision 1.1  2019/02/16 01:37:49  micha
Initial revision

"""
from __future__ import unicode_literals
import sys
import os
import matplotlib.pyplot as plt
import numpy as np
import ntpath
import argparse
import matplotlib
from matplotlib import rc
import io
import re

plt.rcParams["font.family"]="Times New Roman"
plt.rcParams.update({"font.family": "Times New Roman"})
plt.rc("font",serif="Times New Roman")
matplotlib.rcParams["xtick.direction"]="in"
matplotlib.rcParams["ytick.direction"]="in"
"""
usage: ./plotcs.py [-h] [-s str] [-l float] [-q] [-t] [-v] str

Plot MCLZ cross-sections.

positional arguments:
  str         Input file.

optional arguments:
  -h, --help  Show help message and exit.
  -s str      Save image file.
  -l float    Legend font size.
  -q          Quiet; do not display plot.
  -t          Title.
  -v          Verbose. Intended for debugging.
"""

def MainMenu(argv):
    parser=argparse.ArgumentParser(description="Plot MCLZ cross-sections.",prog=sys.argv[0])
    parser.add_argument("InFile",help="Input file.",type=argparse.FileType('r'),metavar="str",default=sys.stdin)
    parser.add_argument("-s",help="Save image file.",type=str,metavar="str",dest="ImgFile")
    parser.add_argument("-l",help="Legend font size.",type=float,metavar="float",dest="l")
    parser.add_argument("-a",help="Axes font size.",type=float,metavar="float",dest="a")
    parser.add_argument("-q",help="Quiet; do not display plot.",action="store_true",dest="quiet")
    parser.add_argument("-t",help="Title.",action="store_true",dest="Title",default=False)
    parser.add_argument("-v",help="Verbose. Intended for debugging.",action="store_true",dest="Verbose",default=False)
    parser._actions[0].help="Show help message and exit."
args=parser.parse_args(None if argv else ["-h"])
    if(args.Verbose):
        for i in vars(args):
            print("%s=%s"%(i,getattr(args,i)))
return args

"""
data contains columns x y_0 ... y_n
labels is a list of strings which correspond to the data columns.
title is a string that contains the title of the plot.
args contains what was specified on the command line.

This function builds a figure and a legend, which can be plotted or saved as 
an image file.
"""
def MakeFig(data,labels,title,args):
    rows=len(data)
    cols=len(data[0])
    xmin=min(data[:,0])
    xmax=max(data[:,0])
    fig=plt.figure(args.InFile.name)
    fig.set_size_inches(16.0,9.0)
    fig.set_dpi(120)
    plt.style.use("classic")
#    plt.style.use("default")
    plt.plot(data[:,0],data[:,-1],'-',color="Black",label=labels[-1],linewidth=2.5)
    color_idx=np.linspace(0,1,cols-2)
    for i,j in zip(range(cols-2,0,-1),color_idx):
        lab=re.sub(r"([a-z])(\d\d)",r"\g<1>^\g<2>",labels[i-1])
        lab=re.sub(r"([a-z])(\d\()",r"\g<1>^\g<2>",lab)
        lab=re.sub(r"(\d)([A-Z])",r"^\g<1>\\rm{\g<2>}",lab)
        lab=re.sub(r"([¹²])([A-Z])",r"\g<1>\\rm{\g<2>}",lab)
        plt.plot(data[:,0],data[:,i],'-',color=plt.cm.gist_rainbow(j),label='$'+lab+'$',linewidth=2.5) 
#    plt.title(args.InFile.name)
    if(args.Title):
        plt.title('$'+title+'$',fontsize=12)
    plt.ylim(ymin=1e-6)
    plt.xlim(xmin,xmax)
#    plt.grid(which='major',linestyle='-',linewidth='0.3')
    fontsize=12
    if(args.a):
        fontsize=args.a
    plt.xlabel(r'energy (eV/u)',fontsize=fontsize)
    plt.ylabel(r'cross section (10$^{-16}$ cm$^{2}$)',fontsize=fontsize)
    plt.xscale('log',basex=10)
    plt.yscale('log',basey=10)
#    leg=plt.legend(loc=2,bbox_to_anchor=(1.005,1.00),frameon=False)
    if(args.l):
        fsize=args.l
    else:
        fsize="large"
        if(cols>24 and cols<31):fsize="medium"
        elif(cols>30 and cols<39):fsize="small"
        elif(cols>38 and cols<43):fsize="x-small"
        elif(cols>42 and cols<46):fsize="xx-small"
        elif(cols>45 and cols<48): fsize=4
        elif(cols>47):fsize=3
    leg=plt.legend(loc=6,bbox_to_anchor=(1.0,0.50),frameon=False,fontsize=fsize)
    return fig,leg

def main(argv):
    matplotlib.rcParams['text.usetex']=True
    matplotlib.rcParams['text.latex.unicode']=True
    reload(sys)
    sys.setdefaultencoding('utf8')
    rc('font',**{'family':'serif','serif':['Times New Roman']})
    rc('text', usetex=True)

    args=MainMenu(argv)
#read it to get labels from comments
    linenum=0
    with io.open(args.InFile.name,encoding="utf-8",errors="ignore") as f:
        for line in f:
            if(linenum==2):
                title=re.sub('^# ','',line).rstrip()
                title=re.sub("\^(\w+)\+","^{\g<1>+}",title) # This puts brackets around the superscripts.
                title=re.sub(r"(\w+)",r"\\rm{\g<1>}",title) # This puts "\rm{}" around the alphanums to remove formatting.
                title=re.sub(r"->",r"\\rightarrow",title).replace(" ","") # This replaces "->" with "\rightarrow"
            if(line.strip().startswith("# (eV/u)")):
#                line=re.sub(r"([A-Z]+)",r"\\rm{\g<1>}",line)
                labels=line.split()
            linenum=linenum+1
    f.close()
#load the data from input
    data=np.loadtxt(args.InFile)

    fig,leg=MakeFig(data,labels[2:],title,args)

    if(args.quiet==False):
        plt.show()
    if(args.ImgFile):
        fig.savefig(args.ImgFile,dpi=120,bbox_inches="tight")

if __name__=="__main__":
    main(sys.argv[1:])

我希望结果图中的标签显示上标数字,就像它们在注释行中一样。 我希望图表上的文本字体为New Times Roman。但是无论我做什么,都不会改变。您可以看到我在代码中尝试过的一些东西(所有这些都是我从stackoverflow获得的解决方案)。但是它们都不起作用。

0 个答案:

没有答案