3
$\begingroup$

In my code, I would like to keep these options fixed

PlotRangePadding -> None, 
PlotRangeClipping -> False, 
ImagePadding -> 80   

So, using Plot I could clip the curves nicely along X-axis using RegionFunction but not along Y-axis. How can I fix that?

Plot[
 {x, -4 x}, {x, -5, 5}, 
 PlotStyle -> {
   Directive[Thickness[0.01], Red, CapForm["Butt"]], 
   Directive[Thickness[0.01], Blue, CapForm["Butt"]]
 }, 
 PlotRange -> {{-1, 0}, {-3, 3}}, 
 Frame -> True, 
 PlotLegends -> 
  Placed[
   LineLegend[{"Y1", "Y2"}, LegendLayout -> {"Row", 1}, LegendMarkerSize -> 20],
   {{0.5, 0.5}, {0, -4.6}}
  ], 
 PlotRangePadding -> None, 
 PlotRangeClipping -> False, 
 ImagePadding -> 80,
 RegionFunction -> (-1 <= # <= 0 &),    
 ImageSize -> 600
]   

enter image description here

Then I have data and need to use ListLinePlot with the same options but did clipping does not work at all now?

ListLinePlot[
 {Table[{x, x}, {x, -5, 5, 0.1}], 
  Table[{x, -4 x}, {x, -5, 5, 0.1}]}, 
 PlotStyle -> {
   Directive[Thickness[0.01], Red, CapForm["Butt"]], 
   Directive[Thickness[0.01], Blue, CapForm["Butt"]]
 }, 
 PlotRange -> {{-1, 0}, {-3, 3}}, 
 Frame -> True, 
 PlotLegends -> 
  Placed[
   LineLegend[{"Y1", "Y2"}, LegendLayout -> {"Row", 1},  LegendMarkerSize -> 20], 
   {{0.5, 0.5}, {0, -4.6}}
  ], 
 PlotRangePadding -> None, 
 PlotRangeClipping -> False, 
 ImagePadding -> 80,
 RegionFunction -> (-1 <= # <= 0 &), 
 ImageSize -> 600
]    

enter image description here

Update 1

As @Daniel Huber mentioned, the problem can be perfectly solved if I set PlotRangeClipping -> True, however, I lose control over the legend position. using Placed[...., {{0.5, 0.5}, {0, -4.6}}] allows me to precisely move the legend position at any point which is possible with PlotRangeClipping -> False. For example, in the case of ListLinePlot

ListLinePlot[{Table[{x, x}, {x, -5, 5, 0.1}], 
  Table[{x, -4 x}, {x, -5, 5, 0.1}]}, 
 PlotStyle -> {Directive[Thickness[0.01], Red, CapForm["Butt"]], 
   Directive[Thickness[0.01], Blue, CapForm["Butt"]]}, 
 PlotRange -> {{-1, 0}, {-3, 3}}, Frame -> True, 
 PlotLegends -> 
  Placed[LineLegend[{"Y1", "Y2"}, LegendLayout -> {"Row", 1}, 
    LegendMarkerSize -> 20], Above], PlotRangePadding -> None, 
 PlotRangeClipping -> True, ImagePadding -> 80, ImageSize -> 600]

enter image description here

this gives the desired clip but how can I precisely align the legend inside the green rectangle?

Update 2

As suggested by @CA Trevillian to use Legended. The problem is that legend disappear at the corner and can not be viewed outside the Frame

Legended[ListLinePlot[{Table[{x, x}, {x, -5, 5, 0.1}], 
   Table[{x, -4 x}, {x, -5, 5, 0.1}]}, 
  PlotStyle -> {Directive[Thickness[0.01], Red, CapForm["Butt"]], 
    Directive[Thickness[0.01], Blue, CapForm["Butt"]]}, 
  PlotRange -> {{-1, 0}, {-3, 3}}, Frame -> True, 
  PlotRangePadding -> None, PlotRangeClipping -> True, 
  ImagePadding -> 80, ImageSize -> 600], 
 Placed[{LineLegend[{Directive[Thick, Red], 
     Directive[Thick, Blue]}, {"Y1", "Y2"}]}, {{0.5, 
    0.5}, {-2.3, -2.2}}]]  

enter image description here

$\endgroup$
1
  • $\begingroup$ RegionFunction is not a valid option for List(Line)Plot. Doesn't it get highlighted in red in the code in your notebook? $\endgroup$
    – MarcoB
    Commented Jan 25, 2022 at 13:17

3 Answers 3

3
$\begingroup$

Update: Using the options PlotRangeClipping -> True and ClippingStyle -> None gives the desired result:

Plot[{x, -4 x}, {x, -5, 5}, 
 PlotStyle -> {Directive[Thickness[0.01], Red, CapForm["Butt"]], 
   Directive[Thickness[0.01], Blue, CapForm["Butt"]]}, 
 PlotRange -> {{-1, 0}, {-3, 3}}, 
 Frame -> True, 
 ImagePadding -> 80, 
 PlotLegends -> 
  Placed[LineLegend[{"Y1", "Y2"}, LegendLayout -> {"Row", 1}, 
    LegendMarkerSize -> 20], {{2/3, 1}, {.25, 2.5}}], 
 PlotRangePadding -> None, 
 PlotRangeClipping -> True, 
 ClippingStyle -> False, 
 RegionFunction -> (-1 <= # <= 0 &), 
 ImageSize -> 600]

enter image description here

As noted by @valarmorghulis in comments, we can remove the options ``PlotRangeClipping -> TrueandClippingStyle -> Noneto get the same output (since these are default options forPlotandListLinePlot`).

Original answer:

plot1 = Plot[{x, -4 x}, {x, -5, 5}, 
  PlotStyle -> {Directive[Thickness[0.01], Red, CapForm["Butt"]], 
    Directive[Thickness[0.01], Blue, CapForm["Butt"]]}, 
  PlotRange -> {{-1, 0}, {-3, 3}},
  Frame -> True, 
  ImagePadding -> 80, 
  PlotLegends -> 
   Placed[LineLegend[{"Y1", "Y2"}, LegendLayout -> {"Row", 1}, 
     LegendMarkerSize -> 20], {{0.5, 1}, {0, 2.5}}], 
  PlotRangePadding -> None, 
  PlotRangeClipping -> False, 
  RegionFunction -> (-1 <= # <= 0 &), 
  ImageSize -> 600]

enter image description here

MapAt[Show[#, PlotRangeClipping -> True] &, plot1, {1}]

enter image description here

$\endgroup$
4
  • $\begingroup$ that is brilliant, Thanks, Man. Just one question please: these two choices in Placed give the same location 1. Placed[LineLegend[{"Y1", "Y2"}, LegendLayout -> {"Row", 1}, LegendMarkerSize -> 20], {{0.5, 1}, {-0.74, 2.4}}] 2. Placed[LineLegend[{"Y1", "Y2"}, LegendLayout -> {"Row", 1}, LegendMarkerSize -> 20], {{0.5, 0.5}, {-1.2, -4.2}}] but when apply your approach the second legend does not appear. can you please explain this? I notice that you also change this points even though it gives the same location. $\endgroup$
    – MMA13
    Commented Jan 26, 2022 at 6:21
  • $\begingroup$ @valarmorghulis, not sure why it is happening. $\endgroup$
    – kglr
    Commented Jan 26, 2022 at 17:27
  • 1
    $\begingroup$ I just notice that only the right choice of points in Placed is matters. So, this works too without the options PlotRangeClipping -> True, ClippingStyle -> False but don't know what is happening Plot[{x, -4 x}, {x, -5, 5}, PlotStyle -> {Directive[Thickness[0.01], Red, CapForm["Butt"]], Directive[Thickness[0.01], Blue, CapForm["Butt"]]}, PlotRange -> {{-1, 0}, {-3, 3}}, Frame -> True, ImagePadding -> 80, PlotLegends -> Placed[LineLegend[{"Y1", "Y2"}, LegendLayout -> {"Row", 1}, LegendMarkerSize -> 20], {{2/3, 1}, {1/4, 5/2}}], ImageSize -> 600] $\endgroup$
    – MMA13
    Commented Jan 27, 2022 at 7:20
  • $\begingroup$ @valarmorghulis, you are right. PlotRangeClipping -> True and ClippingStyle -> None are default values for Plot options; so they are not really needed. $\endgroup$
    – kglr
    Commented Jan 27, 2022 at 11:22
2
$\begingroup$

This regards the "ListPlot" question. I do not understand why you set PlotRangeClipping -> False and then complain about the clipping is not working.

Anyway, you can do what you want by by selecting only those data points in range. E.g.:

ListLinePlot[{Select[
   Table[{x, x}, {x, -5, 5, 0.1}], -1 <= #[[1]] <= 0 &], 
  Select[Table[{x, -4 x}, {x, -5, 5, 0.1}], -1 <= #[[1]] <= 0 &]}, 
 PlotStyle -> {Directive[Thickness[0.01], Red, CapForm["Butt"]], 
   Directive[Thickness[0.01], Blue, CapForm["Butt"]]}, 
 PlotRange -> {{-1, 0}, {-3, 3}}, Frame -> True, 
 PlotLegends -> 
  Placed[LineLegend[{"Y1", "Y2"}, LegendLayout -> {"Row", 1}, 
    LegendMarkerSize -> 20], {{0.5, 0.5}, {0, -4.6}}], 
 PlotRangePadding -> None, PlotRangeClipping -> False, 
 ImagePadding -> 80, ImageSize -> 600]

enter image description here

$\endgroup$
5
  • $\begingroup$ I set PlotRangeClipping -> False to gain precise control on the legend such that I can put it at any point not just at any random location using Above or Right $\endgroup$
    – MMA13
    Commented Jan 25, 2022 at 13:25
  • 1
    $\begingroup$ @valar morghulis you might try using something like Legended instead, to overcome such a limitation. $\endgroup$ Commented Jan 25, 2022 at 13:29
  • $\begingroup$ @CA Trevillian, kindly see my update 1 $\endgroup$
    – MMA13
    Commented Jan 25, 2022 at 13:47
  • 1
    $\begingroup$ @valar morghulis your update does not mention any attempt to use Legended. I recommend investigating this function to see if it can solve your problem! $\endgroup$ Commented Jan 25, 2022 at 16:23
  • $\begingroup$ @CA Trevillian, kindly see update 2. $\endgroup$
    – MMA13
    Commented Jan 25, 2022 at 19:27
0
$\begingroup$

This might be too long for a comment so I will share my finding as an answer

According to the detailed answer by @kglr there are different ways to get the desired clipping.

My problem was that I would like to put the legend at a specific position outside the Frame which requires me to use the option PlotRangeClipping -> False and this caused the mess in the clipping. I found out that we can place the legend outside the Frame with keeping PlotRangeClipping -> True by choosing the correct points in Placed as follows

Plot[{x, -4 x}, {x, -5, 5}, 
 PlotStyle -> {Directive[Thickness[0.01], Red, CapForm["Butt"]], 
   Directive[Thickness[0.01], Blue, CapForm["Butt"]]}, 
 PlotRange -> {{-1, 0}, {-3, 3}}, Frame -> True, ImagePadding -> 80, 
 PlotLegends -> 
  Placed[LineLegend[{"Y1", "Y2"}, LegendLayout -> {"Row", 1}, 
    LegendMarkerSize -> 20], {{2/3, 1}, {1/4, 5/2}}], 
 ImageSize -> 600]  

For example, if we replace the points in Placed by {{0.5, 0.5}, {-1.2, -4.2}} it still gives the correct legend position but to appear outside the Frame I need to use the option PlotRangeClipping -> False, I don't understand what is happening but changing these points makes it work!

The last thing is the discrepancy when export as png or pdf. For png it is perfectly clipped

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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