12
$\begingroup$

I am trying to make a plot of some photoluminescence data, where wavelength is on the x-axis, and intensity is on the y-axis. Also, I would like to have the graph boxed, with the upper x-axis having units of energy in eV, connected to the wavelength through the function: energy=1240/wavelength. I have tried to use the TickLabelFunction in the LevelScheme package, and have only partly succeeded. I can't control the number of decimal points for the ticks on the energy scale. For some reason, N[] doesn't work. Also, the energy tickmarks seem to follow the wavelength ticks, i.e. one energy tick for each wavelength tick. I would like those ticks to be spaced nonlinearly and independently of the other axis, e.g. having them increase with steps of 0.2 eV. Here is a small code that I hope will illustrate my problem.

test = List[{500, 50}];
ListPlot[test, Frame -> True, ImageSize -> 600, 
PlotRange -> {{400, 800}, {-10, 110}}, 
FrameLabel -> {"Wavelength (nm)", "Intensity (a.u.)", "Energy (eV)"},
FrameTicks -> {LinTicks[400, 800, 100, 5], LinTicks, 
LinTicks[400, 800, 100, 5, 
TickLabelFunction -> Function[x, N[1240/x, 2]]], 
StripTickLabels[LinTicks]}]

Any input appreciated, either using the LevelScheme package or not. Thanks!

$\endgroup$
2
  • $\begingroup$ Could you post an image with the "model" of your desired output together with a few points to generate the plot? $\endgroup$ Jul 27, 2012 at 22:08
  • $\begingroup$ Welcome to Mathematica.SE! Did you check this question? It might give you some clues. $\endgroup$ Jul 28, 2012 at 2:19

2 Answers 2

18
$\begingroup$

Here is a method to generate the ticks automatically based on the plot range.

It uses FindDivisions to select "pleasing" values.

eVticks = {1240/#, NumberForm[N@#, {2, 1}]} & /@ FindDivisions[1240/{##}, 8] &;

ListPlot[{{500, 50}},
 Frame -> True, 
 PlotRange -> {{400, 800}, {-10, 110}}, 
 FrameLabel -> {"Wavelength (nm)", "Intensity (a.u.)", "Energy (eV)"},
 FrameTicks -> {{Automatic, Automatic}, {Automatic, eVticks}}
]

Mathematica graphics

With sub-ticks as requested:

eVticks = Join[
    {1240/#, Null} & /@ FindDivisions[1240/{##}, 8*6],
    {1240/#, NumberForm[N@#, {2, 1}]} & /@ FindDivisions[1240/{##}, 8]
   ] &;

Mathematica graphics

$\endgroup$
5
  • $\begingroup$ I like both of the solutions here. But what about minor tick marks, how would you get those in there, and get them to be non-linear? $\endgroup$
    – GOt
    Jul 28, 2012 at 16:58
  • $\begingroup$ @GOt I added a method to my answer. I have not tested it extensively but I believe it is correct. If you find that irregularity in the sub-ticks occurs I'll provide another method. $\endgroup$
    – Mr.Wizard
    Jul 28, 2012 at 20:24
  • $\begingroup$ Thanks so much! It seems to work perfectly. $\endgroup$
    – GOt
    Jul 28, 2012 at 21:44
  • $\begingroup$ It might be a good idea to isolate the 1240/# stuff in a function to make the routine easier to generalize. $\endgroup$ Aug 2, 2012 at 13:16
  • $\begingroup$ @Sjoerd this is merely an illustration, not a packaged solution. There are a number of things I would add if I were making this a reusable function. $\endgroup$
    – Mr.Wizard
    Aug 2, 2012 at 14:01
10
$\begingroup$

I would define my upper ticks so that it should be easy to change the number of decimal points if needed (thanks to Mr.Wizard for pointing out a mistake).

upperTicks = Module[{labels, positions},
 labels = Range[1240/400, 1240/800, -0.2];
 positions = 1240/# & /@ labels;
 Transpose[{positions, labels}]];

upperTicksMinor = Module[{labels, positions, size}, 
 labels = Range[1240/350, 1240/850, -0.05];
 positions = 1240/# & /@ labels;
 labels = "" & /@ Range[Length[labels]];
 size = {0, 0.002} & /@ Range[Length[labels]];
 Transpose[{positions, labels, size}]];

and then use them :

ListPlot[test, Frame -> True, ImageSize -> 600, 
 PlotRange -> {{400, 800}, {-10, 110}}, 
 FrameLabel -> {"Wavelength (nm)", "Intensity (a.u.)", "Energy (eV)"},
 FrameTicks -> {{Automatic, None}, {Automatic, 
 Join[upperTicks, upperTicksMinor]}}]

plot

$\endgroup$
6
  • $\begingroup$ Your top ticks run the opposite direction from the example that the OP gave. Also, he wrote: " I would like those ticks to be spaced nonlinearly ..." $\endgroup$
    – Mr.Wizard
    Jul 28, 2012 at 7:58
  • $\begingroup$ @Mr.Wizard Yes I inverted the direction - will fix it. Isn't the OP asking for 0.2 eV increments though ? $\endgroup$ Jul 28, 2012 at 8:03
  • $\begingroup$ When I run the OP's code I get this. Note the function 1240/x. $\endgroup$
    – Mr.Wizard
    Jul 28, 2012 at 8:07
  • $\begingroup$ Looking good. +1 $\endgroup$
    – Mr.Wizard
    Jul 28, 2012 at 8:19
  • $\begingroup$ I like both of the solutions here. But what about minor tick marks, how would you get those in there, and get them to be non-linear? $\endgroup$
    – GOt
    Jul 28, 2012 at 16:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.