最近我发现了以下情节:
我很好奇,是否可以用 Gnuplot(或其他软件)来实现类似的功能?我确实有三列数据,即距离角能量。有人有什么想法吗?
答案1
考虑渐近线。它是免费的、开源的、跨平台的,使用C++
类似语言来描述矢量图形和处理数据,并与 合作LaTeX
以呈现文本标签。它包含在或多或少最近的LaTeX
发行版中(例如TexLive
)。
例如,该图试图模拟所讨论的图片(功能是任意的,只是为了获得稍微相似的外观):
它是由Asymptote
代码生成的
//
// plotfigure.asy
//
// run
// asy plotfigure.asy
// to get plotfigure.pdf
settings.tex="pdflatex";
import graph;
import palette;
real w=9cm,h=w;
size(w,h,IgnoreAspect);
import fontsize;defaultpen(fontsize(9pt));
texpreamble("\usepackage{lmodern}\usepackage[free-standing-units=true]{siunitx}");
real xmin=-2,xmax=7;
real ymin=-22,ymax=0;
real dxmin=0.2;
real dxmax=0.4;
real dymin=0;
real dymax=0;
string NoLabel(real x){return "";}
typedef real realFuncReal(real);
realFuncReal f(real z){
return
new real(real t){
real x=t*0.6;
return 10*z*(-exp(-x^2)-2*exp(-(x-2.2)^2));
};
}
real phiMin=-5.7, phiMax=171.9;
int n=2000;
//int n=100;
pen[] pal=Wheel(n);// BWRainbow(n);
n=pal.length;
real t;
for(int i=0;i<n;++i){
t=i/(n-1);
draw(graph(f(t),xmin,xmax),pal[i]);
}
void PaletteBar(pen[] pal,transform tr=identity()){
guide bar=box((-1,-1),(1,1));
int n=pal.length-1;
for(int i=0;i<n;++i){
axialshade(tr*box((-1,-1)+(2*i/n,0),(-1,-1)+(2*(i+1)/n,2))
,pal[i ], (-1,-1)+(2*i/n, 0)
,pal[i+1], (-1,-1)+(2*(i+1)/n,0)
);
}
}
void PaletteLabels(string[] lab,real[] labRelPos,transform tr=identity()){
int n=lab.length;
assert(n==labRelPos.length);
for(int i=0;i<n;++i){
label(lab[i],tr*(-1+2*labRelPos[i],-1), shiftless(tr)*plain.S);
}
}
xaxis("Distance (\angstrom)", YEquals(ymin),xmin-dxmin,xmax+dxmax,RightTicks(Step=1,step=0.5 ));
xaxis(YEquals(ymax),xmin-dxmin,xmax+dxmax,LeftTicks(Step=1,step=0.5,ticklabel=NoLabel ));
yaxis("Free Energy (kkal/mol)"
,XEquals(xmin-dxmin),ymin-dymin,ymax+dymax,LeftTicks (Step=2,step=1)
);
yaxis(
XEquals(xmax+dxmax),ymin-dymin,ymax+dymax,RightTicks (Step=2,step=1,ticklabel=NoLabel)
);
transform tr=shift(1,-16)*rotate(-90)*scale(2,0.25);
PaletteBar(pal,tr);
real labPosCalc(real labVal){
return (labVal-phiMin)/(phiMax-phiMin);
}
real[] palLabelValue={-5.7,83.1,171.9};
PaletteLabels(
sequence(new string(int n){return string(palLabelValue[n]);}, palLabelValue.length ),
sequence(new real(int n){return labPosCalc(palLabelValue[n]);}, palLabelValue.length ),
tr
);
label(rotate(90)*("Angle (\degree)"),shift(-1,0)*tr*(0,-1),plain.W);
shipout(bbox(Fill(paleyellow)));