Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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!

share|improve this question
    
Could you post an image with the "model" of your desired output together with a few points to generate the plot? –  belisarius Jul 27 '12 at 22:08
    
Welcome to Mathematica.SE! Did you check this question? It might give you some clues. –  Sjoerd C. de Vries Jul 28 '12 at 2:19

2 Answers 2

up vote 11 down vote accepted

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

share|improve this answer
    
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? –  GOt Jul 28 '12 at 16:58
    
@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. –  Mr.Wizard Jul 28 '12 at 20:24
    
Thanks so much! It seems to work perfectly. –  GOt Jul 28 '12 at 21:44
    
It might be a good idea to isolate the 1240/# stuff in a function to make the routine easier to generalize. –  Sjoerd C. de Vries Aug 2 '12 at 13:16
    
@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. –  Mr.Wizard Aug 2 '12 at 14:01

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

share|improve this answer
    
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 ..." –  Mr.Wizard Jul 28 '12 at 7:58
    
@Mr.Wizard Yes I inverted the direction - will fix it. Isn't the OP asking for 0.2 eV increments though ? –  b.gatessucks Jul 28 '12 at 8:03
    
When I run the OP's code I get this. Note the function 1240/x. –  Mr.Wizard Jul 28 '12 at 8:07
    
Looking good. +1 –  Mr.Wizard Jul 28 '12 at 8:19
    
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? –  GOt Jul 28 '12 at 16:58

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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