缘由
地球物理文献里有很多公式,也有很多曲线。详细研究这些文献时(尤其是需要用到文章中的某部分时),通常需要再现出作者的某些图片,以证明自己确实明白这些公式或原理。当自己做出图后,发现只有将作者原图截图下来,放在某些软件中(如excel,origin)再添加上自己画的图,并且要不断的调整取值范围等。图片较少,也就罢了;图片很多,或者多次算出结果,再去调整这些细节,很费时。本人一直在寻找解决办法,发现一个帖子,可以解决:MATLAB叠图
但是,MATLAB的作图不太美观,最主要的是难以生成透明的图像(alpha=0这些都不太好用),故考虑python提供的matplotlib库。【今日先暂停于此,待python代码写好后再更新】
更新
1. MATLAB如何传递参数(或命令)到python解释器:
cmdstr=['python -c "import PythonFigs; PythonFigs.ReproduceFigs(BackFigsPath=r''',BackFigsPath,''',DataPath=r''',DataPath,''',NewFigsPath=r''',NewFigsPath,''',xyrange=[',num2str(ranges(1)),',',num2str(ranges(2)),',',num2str(ranges(3)),',',num2str(ranges(4)),'],x=',num2str(x),',y=',num2str(y),')"'];
status=system(cmdstr);
这里使用system将启动一个shell,并将参数cmdstr传递给shell,相当于在shell里输入了cmdstr那一串命令。cmdstr命令包括使用python的解释器,命令参数-c,使用模块PythonFigs,调用函数ReproduceFigs。函数(方法)中依次是背景图片的位置,要画的图像的数据,新图像要保存的位置,画图的x,y范围。
2.Python中相应MATLAB的调用:
# -*- coding: utf-8 -*-
# Produce images in literatures for given x,y ranges
import os
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import MultipleLocator
from matplotlib.ticker import FormatStrFormatter
from pprsv.pprsv import *
import xlrd
import xlwt
import matplotlib.image as mpimg
#vis = pprsv()
def ReproduceFigs(BackFigsPath=r'E:\MELTS\Capture.JPG',DataPath=r'E:\MELTS\korenaga\LITHOS\LithosInitial.xlsx',NewFigsPath=r'E:\MELTS\trypython.png',xyrange=[3150,3460,150,0]):
###Read image data from files, not from MATLAB memory for compatible issues
DPI_Def=200 #defaul dpi (pixels within each inch)
workbook=xlrd.open_workbook(DataPath) #open Excel
#print workbook.sheet_names() #check how many sheets here
sheet=workbook.sheet_by_index(0) #load sheet1 content; index starts from 0
#sheet=workbook.sheet_by_name('rho2') #load rho2 content
#print sheet.name,sheet.nrows,sheet.ncols
yrow=sheet.col_values(8) #index starts from 0
xrow=sheet.col_values(2) #possibly many rows
#print yrow[2:]
#print xrow[1:]
###Visualization
fig,ax=plt.subplots() #get current figure and axis
xmjl = MultipleLocator(50) #x axis major tick
xmnl = MultipleLocator(10) #x axis minor tick
ymjl = MultipleLocator(50) #y axis major tick
ymnl = MultipleLocator(10) #y axis minor tick
xmjf = FormatStrFormatter('%.0f') #x axis text format
ymjf = FormatStrFormatter('%.0f') #y axis text format
ax.xaxis.set_major_locator(xmjl)
ax.xaxis.set_major_formatter(xmjf)
ax.yaxis.set_major_locator(ymjl)
ax.yaxis.set_major_formatter(ymjf)
ax.xaxis.set_minor_locator(xmnl)
ax.yaxis.set_minor_locator(ymnl)
plt.plot(xrow[1:],yrow[1:],color='red',linewidth=3,linestyle='--') #some NaN in file
#plt.title('Density Profile',fontsize=28)
#ax.text(3280,-20,(r"$\mathrm{ \mathbf{ Density\:[kg/m^3]}}$"),fontsize=10)
#plt.ylabel(r"$\mathrm{ \mathbf{ Depth\:[km]}}$",fontsize=10)
plt.tick_params(axis='both',which='major',labelsize=15)
plt.axis([xyrange[0],xyrange[1],xyrange[2],xyrange[3]]) #x_min, x_max, y_min, y_max
#ax.invert_yaxis() #invert y axis
ax.xaxis.set_ticks_position('top')
ax.yaxis.set_ticks_position('left')
TempImg=mpimg.imread(BackFigsPath)
sizecub=TempImg.shape #size of image
plt.rcParams['figure.figsize']=(sizecub[1]/DPI_Def,sizecub[0]/DPI_Def)
#fig.set_size_inches(sizecub[1]/DPI_Def,sizecub[0]/DPI_Def)#width, length
plt.savefig(NewFigsPath,format='png',bbox_inches='tight',dpi=3.0*DPI_Def,transparent=True)
plt.imshow(TempImg,alpha=1.0,extent=xyrange)
plt.show()
#ReproduceFigs()
这里都是python语法,无需说明。该脚本除了可以被MATLAB调用,还可以独立运行,只需去掉最后一行的注释,方法默认的路径等可以自由修改。
希望给有需要的同学一些启发。