What's the most effective way to make tick marks not overlap with axes edges?

Here's an example plot with a couple things I marked on it:

Here's the code:

tixval = {{0, 1}, {0, 1}} /. {0 -> None, 1 -> All};
frameval = frameopts /. {0 -> False, 1 -> True};
dat = Table[{i, i^2}, {i, 0, 5, .2}];
ListPlot[dat, FrameTicks -> tixval, Frame -> frameval,
FrameLabel -> {{"", Rotate[#, Pi] &@"meow"}, {"", "woof"}},
LabelStyle -> 18,
PlotRange -> {{dat[[1, 1]], dat[[-1, 1]]}, {dat[[1, 2]],
dat[[-1, 2]]}}]


There are two things I'd like to change about the ticks, but I'm pretty sure they'd both be solved by the same solution. I've shown them with the red line and circle in the picture above. The line is showing that the '0' for the horizontal axis is centered with the tick mark, which makes sense. Unfortunately, this is a little messy when it's directly next to another figure (to its left). It means either the 0 is overlapping that figure, or there has to be a gap I'd rather not have.

Relatedly, the red circle is showing the effect on the other side, where the largest tick values for the two axes are getting too cozy and crowding the image, in my opinion.

What I'd like to do is solve both of these problems, with three caveats:

1. I want it to be fairly automated, in the sense that I don't want to just write a list of the tick marks each time. It's part of a larger function that I can't manually manipulate each time.
2. I want the tick mark values to be round numbers (I know "round" is relative, so basically as round as possible), not like {0, 1.3, 2.6, ...}.
3. I can't change the PlotRange. I know that's inconvenient, but that needs to be set by another part of this function.

One thing I've tried (that solves the problem of the largest tick marks overlapping) is the following. I basically produce the list of tick marks to be used, and remove the last one of each. However, the are obviously lots of ways to do this and also the question of how much to remove, and how to keep the numbers round. Here's one implementation:

tixval = {{0, 1}, {0, 1}} /. {0 -> None, 1 -> All};
frameval = frameopts /. {0 -> False, 1 -> True};
dat = Table[{i, i^2}, {i, 0, 5, .2}];
xticks = Most@
Subdivide[Floor@dat[[1, 1]], Floor@Round[dat[[-1, 1]], 5], 5]
yticks = Most@
Subdivide[Floor@dat[[1, 2]], Floor@Round[dat[[-1, 2]], 5], 5]
ListPlot[dat, FrameTicks -> {{None, yticks}, {None, xticks}},
Frame -> frameval,
FrameLabel -> {{"", Rotate[#, Pi] &@"meow"}, {"", "woof"}},
LabelStyle -> 18,
PlotRange -> {{dat[[1, 1]], dat[[-1, 1]]}, {dat[[1, 2]],
dat[[-1, 2]]}}]


I just made it so it is going to have 5 tick marks for each, which is fine with me. It should work as long as the maximum values aren't too small, which we can assume is the case. Here's how it looks:

However, it honestly looks a little weird with that big gap there, and the problem with the 0 still isn't solved.

Is there some clever Mathematica way of doing this?

• I am unable to reproduce your plots from your code, probably because frameopts is undefined. – bbgodfrey Sep 22 '16 at 1:31