0
$\begingroup$

I want to plot vertical lines given by some equation in my code below. I want this vertical line to touch x-axis with years and the axis directly above it which closes the graph at a point x=year specified by the equation. My problem is that whenever I change the y value on the line to get line that touches the base of x-axis and the axis above it the PlotRange of left and right axes change and my line doesn't "close the plot".

The question may be frased differently: How to plot vertical line that touches x-axis(the one with years) at some specified point x=year and the axis above it, therefore closing the graph ?

Let me say that I tried GridLines but somehow they don't show up if I use TwoAxisListLinePlot. Edit: The code should be extensible to more lines that one.

  TwoAxisListLinePlot[{f_, g_}, plotopts : OptionsPattern[]] := 
  Module[{fgraph, ggraph, frange, grange, fticks, 
   gticks}, {fgraph, ggraph} = 
   MapIndexed[
   ListPlot[#, Joined -> True, 
  FrameTicksStyle -> Directive[Thickness[0.003], Black, 12], 
  TicksStyle -> Directive[Thickness[0.003], Black, 12], 
  Axes -> True, PlotRange -> All, 
  PlotStyle -> ColorData[1][#2[[1]]]] &, {f, g}]; {frange, 
grange} = 
 Last[PlotRange /. AbsoluteOptions[#, PlotRange]] & /@ {fgraph, 
 ggraph};
 fticks = 
  Last[Ticks /. 
  AbsoluteOptions[fgraph, 
   Ticks]] /. _RGBColor | _GrayLevel | _Hue :> ColorData[1][1] ;
  gticks = (MapAt[Function[r, Rescale[r, grange, frange]], #, {1}] & /@
   Last[Ticks /. 
    AbsoluteOptions[ggraph, 
     Ticks]]) /. _RGBColor | _GrayLevel | _Hue -> ColorData[1][2];
   Show[fgraph, 
 ggraph /. 
Graphics[graph_, s___] :> 
 Graphics[
  GeometricTransformation[graph, 
   RescalingTransform[{{0, 1}, grange}, {{0, 1}, frange}]], s], 
  Axes -> False, Frame -> True, 
 FrameStyle -> {ColorData[1] /@ {1, 2}, {Automatic, Automatic}}, 
 FrameTicks -> {{fticks, gticks}, {Automatic, Automatic}}, 
 Evaluate[FilterRules[{plotopts}, Options[ListLinePlot]]]]]



 pareto1 = {{2000, 1.254221127}, {2001, 1.347243255}, {2002, 
1.38218106}, {2003, 1.313844733}, {2004, 1.3734142182}, {2005, 
1.298813854}, {2006, 1.253782028}, {2007, 1.2306716}, {2008, 
1.3409995784}, {2009, 1.21464622}, {2010, 1.1720606}, {2011, 
1.24292400036}, {2012, 1.19382731433}, {2013, 
1.22420356414}, {2014, 1.2223526}, {2015, 1.307600821757}};
pareto2 = {{1995, 1.677402}, {1999, 1.7299}, {1998, 1.8988961}, {1997,
1.8543884}, {2006, 3.2155496200}, {2007, 2.242218}, {2008, 
 3.892772}, {2009, 2.937621}, {2010, 2.055810}, {2012, 
 2.03939198}, {2014, 1.76645}, {2015, 1.661591900}, {2013, 1.7859}}

c2002 = Normal@
ContourPlot[x == 2002, {x, 1995, 2015}, {y, 1, 1.43}, 
ContourStyle -> {Black, Thickness[0.0015], Dashed}];
ab = TwoAxisListLinePlot[{pareto1, pareto2}, 
Joined -> True, {Frame -> True, PlotLabel -> "", PlotRange -> All, 
Joined -> True, PlotMarkers -> {Automatic, Small}, 
ImageSize -> Large, FrameLabel -> {{"a", "b"}, {"c", ""}}, 
BaseStyle -> {FontSize -> 14}}, 
LabelStyle -> Directive[Black, Bold], 
FrameTicksStyle -> Directive[Thickness[0.003], Black, 12], 
FrameStyle -> Directive[Thickness[0.002], Black, 12], 
PlotRange -> {0, 6}];
Show[ab, c2002]
$\endgroup$
  • $\begingroup$ Show[ab, Epilog -> Cases[c2002, {___, _Line}, Infinity]] $\endgroup$ – Jason B. Feb 20 '17 at 20:57
  • $\begingroup$ It works, can you make it an answer? $\endgroup$ – Caims Feb 20 '17 at 21:00
  • $\begingroup$ By the way, when I try to add a second line it doesn't work. Can I somehow extend your method? $\endgroup$ – Caims Feb 20 '17 at 21:02
  • $\begingroup$ see the revised version below $\endgroup$ – Jason B. Feb 20 '17 at 21:09
5
$\begingroup$

In this case, when you combine the two plots, it seems to take the plot range from the second plot rather than the first. One way to fix this is to use the Graphics primitives from the contour plot as an Epilog for the first.

Look at the InputForm of the contour plot:

Short@InputForm@c2002
(* Graphics[{{{}, {}, Tooltip[{Directive[<<4>>], Line[<<1>>]}, <<1>>]}}, {<<11>>}] *)

It's just a Graphics object. We need to just get whatever is the first argument of that Graphics to use as our Epilog,

First@Apply[List]@c2002//Short
(* {{{},{},{Directive[AbsoluteThickness[1.6],,<<9>>[<<7>>],Dashing[{Small,Small}]],<<1>>}}} *)

Show[ab, Epilog -> First@Apply[List]@c2002]

Mathematica graphics

This works no matter how many lines you had in your ContourPlot,

c200206 = 
 Normal@ContourPlot[{x == 2002, x == 2006}, {x, 1995, 2015}, {y, 1, 
    1.43}, ContourStyle -> {{Black, Thickness[0.0015], Dashed}, {Red, 
      Thickness[0.0015], Dashed}}];
Show[ab, Epilog -> First@Apply[List]@c200206]

Mathematica graphics

As an aside, there are much easier ways to get a vertical line than using ContourPlot,

Show[ab, Epilog -> {Thick, Dashed, Red, Line[{{2002, 1}, {2002, 2}}]}]
$\endgroup$

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.