3

From data test, I want to plot a graph with two x axes (see the image which I have added). Two $x$ axes, one at bottom and other on top. In test data, test[[1 ;; All, 1]] is $x$-axis at bottom, test[[1 ;; All, 2]] is $y$-axis and test[[1 ;; All, 3]] is $x$-axis at top. With my code, second $x$-axis on top is not coming properly.

test={{0.875, 0.000361069, -0.137}, {0.9, -0.000429778, -0.1096},
 {0.925, -0.000102596, -0.0822}, {0.95, -0.000234415, -0.0548}, 
{0.975, -0.00066855, -0.0274},{1., -0.00114038, 0}, {1.025,   0.00278551, 0.0274}, 
{1.05, -0.00148313, 0.0548},{1.075,  0.00132836, 0.0822}, 
        {1.1, -0.000164138, 0.1096}, {1.125, -0.00036032, 0.137}} 
top = test[[All, {1, 3}]]
ListLinePlot[Transpose[{test[[1 ;; All, 1]], test[[1 ;; All, 2]]}], Frame-> True, 
        FrameTicks -> {{Automatic, Automatic}, {Automatic, top}}, 
             PlotRange -> All]

Second x axis on top is not coming properly with my code.

As you can see, the manually specified ticks look awful with their overlapping digits. How could I make them look like the built-in tickmarks, but with a different range?

Jason B.
  • 68,381
  • 3
  • 139
  • 286
RGG
  • 67
  • 7
  • 1
    I don't quite understand you, but maybe you want FrameTicks -> {{All, None}, {All, All}}? – Alan Jan 21 '17 at 14:15
  • 1
    I want to plot a graph with two x axes (see the image which I have added). Two x axes, one at bottom and other on top. In test data, test[[1 ;; All, 1]] is x axis at bottom, test[[1 ;; All, 2]] is y axis and test[[1 ;; All, 3]] is x axis at top. – RGG Jan 21 '17 at 14:56
  • You need to generate custom FrameTicks manually or use something like: (94726) – Kuba Jan 21 '17 at 15:03
  • I don't understand the question. The code you provide already does what you say you want it to do. What else do you need? – Emilio Pisanty Jan 21 '17 at 15:16
  • 1
    With this code, I do not get x axis on top properly. – RGG Jan 21 '17 at 15:22
  • @Raghu - if you use the function extraAxisPlot defined here, then you can enter plot = ListLinePlot[test[[All, ;; 2]], Frame -> True, FrameTicks -> {{Automatic, Automatic}, {Automatic, None}}]; extraAxisPlot[plot, {-.13, .13}, {.875, .0031}] and get this image – Jason B. Jan 21 '17 at 17:35
  • @Jason, I tried extraAxisPlot function, I see an error message while plotting .....Total::normal: Nonatomic expression expected at position 1 in Total[Automatic]. >> – RGG Jan 22 '17 at 03:37
  • @Raghu - You get this message when using this code? What version of Mathematica are you using? – Jason B. Jan 22 '17 at 14:20
  • @JasonB. Mathematica 9. – RGG Jan 22 '17 at 15:34

2 Answers2

3

The method I originally proposed in a comment does not work in version 9, so here is a method that does.

The usage of the Charting`FindTicks function should be clear from this example,

oldXRange = {Min@#, Max@#} & @ test[[All, 1]]
newXRange = {Min@#, Max@#} & @ test[[All, 3]]
(* {0.875, 1.125} *)
(* {-0.137, 0.137} *)

 ListLinePlot[test[[All, ;; 2]], Frame -> True,
 FrameTicks -> {
   {Automatic, Automatic},
   {Automatic, Charting`FindTicks[oldXRange, newXRange]}}]

Mathematica graphics

Jason B.
  • 68,381
  • 3
  • 139
  • 286
2

Rotate the labels

test = {{0.875, 
    0.000361069, -0.137}, {0.9, -0.000429778, -0.1096}, {0.925,
    -0.000102596, -0.0822}, {0.95, -0.000234415, -0.0548}, {0.975,
    -0.00066855, -0.0274}, {1., -0.00114038, 0}, {1.025, 0.00278551, 
    0.0274}, {1.05, -0.00148313, 0.0548}, {1.075, 0.00132836, 
    0.0822}, {1.1, -0.000164138, 0.1096}, {1.125, -0.00036032, 0.137}};

top = {#[[1]], Rotate[ToString[
       NumberForm[#[[3]], {5, 4}]],
      45 Degree]} & /@ test;

Note that you can simplify the extraction of the data list

ListLinePlot[Most /@ test,
 Frame -> True,
 FrameTicks -> {
   {Automatic, Automatic},
   {Automatic, top}},
 PlotRange -> All]

enter image description here

EDIT: If you have a large number of points then using a labeled tick for each point is impractical, as the labeled ticks will be too dense to be useful. Instead I recommend that you use Tooltip

ListPlot[List /@ Most /@ test,
 Frame -> True,
 PlotStyle -> Blue,
 PlotMarkers ->
  (Tooltip[●, #[[3]]] & /@ test),
 Epilog -> Line[Most /@ test]]

enter image description here

Bob Hanlon
  • 157,611
  • 7
  • 77
  • 198
  • Thank you for the Answer. I can rotate the labels only when I have less number of points. For example, if the data points are very large, then it will not be possible to label all the points of a list. Is there any way do it automatically ? like bottom x axis. – RGG Jan 21 '17 at 16:57