Mathematica Asked by Emre on April 24, 2021
From Godbeer et al, Modelling proton tunnelling in the adenine–thymine base pair:
Hello,
Well, I have very similar graph like in the image. I am trying to add that additional measurments like deltaE and EB arrows. I couldnt find a way to express the question better.
Thanks in advance.
You must add these graphical elements in an Epilog by hand. Here is an example how to do it:
d = {1, 0, 1, .5, 1};
pol = InterpolatingPolynomial[d, x];
Plot[pol, {x, 1, 5}, Epilog -> {
Arrowheads[{-0.04, 0.04}],
Arrow[{{3.7, -0.237}, {3.7, 0.236}}],
Arrow[{{2.5, -0.237}, {2.5, 1.02}}],
Dashed,
Line[{{0.5, -0.237}, {5, -0.237}}], Line[{{2, 1.02}, {3.5, 1.02}}],
Line[{{3.5, 0.236}, {5, 0.236}}],
Text[Style["E", 20], {2.7, 0.3}], Text[Style["Del", 20], {4, 0.1}]
}]
Answered by Daniel Huber on April 24, 2021
First a data set that looks like the one behind the picture in OP:
SeedRandom[1]
dt = Table[ {x, Cos[5 Pi x/3]/(5 Pi x/3) + 1/2}, {x, Sort @ RandomReal[{0, 2}, 50]}];
ClearAll[iF]
iF = Interpolation[dt,
"ExtrapolationHandler" -> {Automatic, "WarningMessage" -> False}];
listplot = ListPlot[dt, PlotMarkers -> {"[Cross]", 20}, PlotStyle -> Black];
Show[Plot[iF[x], {x, 0, 2}, PlotStyle -> Directive[Red, Thick, Dotted]], listplot]
plot = Plot[iF[x], {x, 0, 2}, MeshFunctions -> {iF'[#] &},
Mesh -> {{0}}, MeshStyle -> Directive[Red, AbsolutePointSize[15]],
PlotStyle -> Directive[Red, Thick, Dotted]];
Show[plot, listplot]
A convenient graphical trick to identify the extreme points is to use {iF'[#]&}
as the option value for MeshFunctions
and set Mesh -> {{0}}
:
plot = Plot[iF[x], {x, 0, 2}, MeshFunctions -> {iF'[#] &},
Mesh -> {{0}}, MeshStyle -> Directive[Red, AbsolutePointSize[15]],
PlotStyle -> Directive[Red, Thick, Dotted]];
Show[plot, listplot]
Now we can extract the coordinates of Point
s from plot output and use them to add tangent lines passing through those points, annotated arrows marking the vertical displacements from a reference point etc.
First, a helper function to create custom arrowheads with labels:
ClearAll[arrowHeadsLabeled]
arrowHeadsLabeled[lbl_, side_: {1, 0}, dir_: {0, -1}, pos_: .5] :=
Arrowheads[{{-.03, 0}, {.03, 1},
{.03, pos, {Graphics[Text[lbl, {0, 0}, side, dir]], 1}}}]
Example:
Graphics[{arrowHeadsLabeled["LABEL 1"], Red, Arrow[{{1, 0}, {1, 4}}],
arrowHeadsLabeled["LABEL 2", {0, -1}, {1, 0}], Blue,
Arrow[{{3, -1}, {3, 3}}],
arrowHeadsLabeled[Style["LABEL 3", 16], {0, 1.5}, {1, 0}, .25], Green,
Arrow[{{4, 0}, {5, 3}}]}, PlotRange -> {{0, 6}, {-2, 5}},
ImageSize -> Medium]
Next, a function that annotates the output from Plot
with Mesh*
options as in the example above:
ClearAll[annotatedPlot]
annotatedPlot[plt_, labels_, disp_: 1.5] :=
Module[{sortedextrema = SortBy[First]@Cases[Normal[plt], Point[x_] :> x, All], start,
xma, arrows, tangentlines},
start = First@MinimalBy[Last]@sortedextrema;
xma = MovingAverage[Join[{PlotRange[plt][[1, 1]]},
sortedextrema[[All, 1]], {PlotRange[plt][[1, 2]]}], {2, 1}];
arrows = Arrow[Offset[{If[#[[1]] < start[[1]], -5, 10], 0}, #] & /@
Partition[#, 2]] & /@ Thread[{Rest @ Most @ xma, start[[2]],
Rest @ Most @ xma, DeleteCases[sortedextrema, start][[All, 2]]}];
tangentlines = Line /@ DeleteCases[
Thread /@ Transpose[{Partition[xma, 2, 1] , sortedextrema[[All, 2]]}], start];
Show[plt /. Point[_] -> {},
Graphics[{Dashed, tangentlines,
Line[{{sortedextrema[[1, 1]], start[[2]]}, {sortedextrema[[-1, 1]], start[[2]]}}],
Black, Dashing[{}],
MapThread[{arrowHeadsLabeled[#, {disp, 0}], #2} &, {labels, arrows}]}],
ImageSize -> Large, Frame -> True, Axes -> False]]
Examples:
Using plot
and listplot
from the first example above:
labels = {Style[Subscript[InputForm@E, B], 16], Style[∇InputForm@E, 16]};
Show[annotatedPlot[plot, labels], listplot, PlotRange -> {{0, 2}, {0, 1}}]
SeedRandom[1]
dt2 = Table[ {x, Cos[5 Pi x/3]/(5 Pi x/3) + 1/2}, {x, Sort@RandomReal[{0, 4}, 50]}];
ClearAll[iF2]
iF2 = Interpolation[dt2,
"ExtrapolationHandler" -> {Automatic, "WarningMessage" -> False}];
listplot2 = ListPlot[dt2, PlotMarkers -> {"[Cross]", 20}, PlotStyle -> Black];
plot2 = Plot[iF2[x], {x, 0, 4}, MeshFunctions -> {iF2'[#] &},
Mesh -> {{0}}, MeshStyle -> Directive[Red, AbsolutePointSize[15]],
PlotStyle -> Directive[Red, Thick, Dotted]];
labels2 = labellist = Style[Subscript[∇InputForm@E, #], 16] & /@ Range[6];
Show[annotatedPlot[plot2, labels2, -1.5], listplot2]
A variation that takes a data set and labels as input:
ClearAll[annotatedListPlot]
annotatedListPlot[lbls_: Automatic, disp_: 1.5][data_,
opts : OptionsPattern[{Plot, ListPlot}]] :=
Module[{lp = ListPlot[data, opts],
if = Interpolation[data, "ExtrapolationHandler" -> {Automatic,
"WarningMessage" -> False}], plt, lblst},
plt = Plot[if[x], {x, Min[data[[All, 1]]], Max[data[[All, 1]]]},
MeshFunctions -> {if'[#] &}, Mesh -> {{0}}, opts];
lblst = lbls /. Automatic -> (ToString /@
Range[Count[Normal@plt, _Point, All] - 1]);
Show[annotatedPlot[plt, lblst, disp], lp, opts]]
Example:
annotatedListPlot[labellist, -1.5][dt2,
PlotTheme -> {"Minimal", "OpenMarkersThick"},
PlotStyle -> Directive[Red, Thick]]
Answered by kglr on April 24, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP