4
$\begingroup$

As the following image shows, are there any good ways to extend the grid lines to the image margins while keep the original aspect ratio and the label's position unchanged? (In fact, all the features of the original image should not be changed, only extending the grid lines.) enter image description here

The following code is used to create the above image:

data = Transpose[{Range[1964, 2010], RandomInteger[{0, 120}, 47]}];
ListLinePlot[data, PlotStyle -> {Thick, Orange}, 
 PlotRange -> {0, 120}, PlotRange -> {{1964, 2010}, {0, 120}}, 
 PlotRangePadding -> {{0, 1}, None},
 Frame -> {{True, False}, {True, False}},
 FrameTicks -> {{{#, 
       Style[ToExpression[#], Black, 
        FontFamily -> "Times New Roman"], {0.01, 0}} & /@ {0, 30, 60, 
      90, 120}, 
    None}, {{#, 
       Style[ToExpression[#], Black, 
        FontFamily -> "Times New Roman"], {0.01, 0}} & /@ {1964, 1979,
       1995, 2010}, None}},
 FrameStyle -> Gray,
 FrameLabel -> {None, 
   Style["申请量/项", FontFamily -> "宋体", FontSize -> 12, Black]},
 GridLines -> {{1964, 1979, 1995, 2010}, None},
 ImageMargins -> {{0, 0}, {50, 100}}]

I have tried the Overlay and Show functions or Prolog and Epilog options, but I failed to get what I expected.

I appreciate any tips about this problems.

$\endgroup$

2 Answers 2

3
$\begingroup$

You can Inset the plot into an enclosing Graphics. First, I remove the ImageMargins and GridLines from your plot:

data = Transpose[{Range[1964,2010], RandomInteger[{0,120}, 47]}];

plot = ListLinePlot[
    data,
    PlotStyle->{Thick,Orange},
    PlotRange->{{1964,2010},{0,120}},
    PlotRangePadding->{{0,1},None},
    Frame->{{True,False},{True,False}},
    FrameTicks->{{{#,Style[ToExpression[#],Black,FontFamily->"Times New Roman"],{0.01,0}}&/@{0,30,60,90,120},None},{{#,Style[ToExpression[#],Black,FontFamily->"Times New Roman"],{0.01,0}}&/@{1964,1979,1995,2010},None}},
    FrameStyle->Gray,
    FrameLabel->{None,Style["申请量/项",FontFamily->"宋体",FontSize->12,Black]}
];

In order to use Inset, some information about the plot is needed. This information can mostly easily be obtained by using my GraphicsInformation function. Install with:

PacletInstall[
    "GraphicsInformation",
    "Site" -> "http://raw.githubusercontent.com/carlwoll/GraphicsInformation/master"
];

Load with:

<<GraphicsInformation`

Then, the needed plot information is obtained with:

{pad, size} = {"ImagePadding", "ImageSize"} /. GraphicsInformation[plot]

{{{39., 4.26087}, {16., 6.}}, {360., 217.756}}

Finally, we are ready to use Inset:

Graphics[
    {Inset[plot, Offset[{0, 50 + pad[[2,1]]}, Scaled[{0,0}]], Scaled[{0,0}], Offset[size]]},
    AspectRatio->Full,
    ImagePadding->{pad[[1]], {0,0}},
    ImageSize->size + {0, 150},
    GridLines->{{1964,1979,1995,2010},None},
    PlotRange->{{1964,2011},{0,120}}
]

enter image description here

$\endgroup$
1
  • $\begingroup$ Thx for your brilliant idea. Inset is one of the commands I have never thought of. $\endgroup$
    – Z-Y.L
    Jan 9, 2018 at 2:06
2
$\begingroup$

Not sure but I don't think it can be done with ImageMargins. Removing ImageMargins, manually adjusting ImagePadding settings, setting PlotRangeClipping to False, and using Epilog to inject lines we get something close:

verticallines = {Offset[{0, -700}, {#, 0}], Offset[{0, 700}, {#, 0}]} & /@
   {1964, 1979, 1995, 2010};

llp1 = ListLinePlot[data, PlotStyle -> {Thick, Orange}, 
  PlotRange -> {0, 120}, PlotRange -> {{1964, 2010}, {0, 120}}, 
  PlotRangePadding -> {{0, 1}, None}, Frame -> {{True, False}, {True, False}}, 
  FrameStyle -> Gray, GridLines -> {{1964, 1979, 1995, 2010}, None}, 
  PlotRangeClipping -> False, 
  ImagePadding -> {{Automatic, Automatic}, {65, 105}}, 
  Epilog -> {Red, Line[verticallines]}]

enter image description here

llp0 = ListLinePlot[data, PlotStyle -> {Thick, Orange}, 
   PlotRange -> {0, 120}, PlotRange -> {{1964, 2010}, {0, 120}}, 
   PlotRangePadding -> {{0, 1}, None}, 
   Frame -> {{True, False}, {True, False}}, FrameStyle -> Gray, 
   GridLines -> {gl = {1964, 1979, 1995, 2010}, None}, 
   PlotRangeClipping -> False, ImageMargins -> {{0, 0}, {50, 100}}];

Style[Row[{llp1, llp0}], ImageSizeMultipliers -> {1, 1}]

enter image description here

Overlay[{llp1, llp0}, All, 2, Alignment -> {Bottom, Center}]

enter image description here

$\endgroup$
2
  • $\begingroup$ Thx for your advice. But I don't understand well the difference between ImageMargins and ImagePadding. With my preliminary code, if ImageMargins is changed to ImagePadding, my code just gives what I expect. $\endgroup$
    – Z-Y.L
    Jan 9, 2018 at 2:00
  • $\begingroup$ @Z-Y.L, in version 9.0 and version 11.2 I don't get the expected result by simplify replacing Imagemargins with ImagePadding. $\endgroup$
    – kglr
    Jan 9, 2018 at 2:20

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.