3
$\begingroup$

I've looked for a similar question but the one that came up first has no answer, so please bear with me as I am a complete newbie to Mathematica.

My ultimate goal is to generate custom ticks for a plot. The X axis is in minutes (not actual units, just an integer) and represents overnight times from, for example, 10pm to 3am the next day.

I've written a short function in the form of a module to convert a 'minute' value into a string "hh:mm". This works fine.

f[x_] :=
 Module[{q, r},
  {q, r} = QuotientRemainder[x, 60];
  q = Mod[q, 24];
  q = IntegerString[q, 10, 2];
  r = IntegerString[r, 10, 2];
  StringJoin[q, ":", r]
  ]

myTicks[min_, max_] := f /@ FindDivisions[{min, max, 60}, 5]

myTicks[22*60, (3 + 24)*60]
->  {"22:00", "23:00", "00:00", "01:00", "02:00", "03:00"}

What I can't seem to manage is how to combine the two into a single definition of myTicks that avoids the need for the intermediate function f.

Any suggestions, please?

$\endgroup$
  • 2
    $\begingroup$ Look up Function in the documentation. $\endgroup$ – Szabolcs Feb 21 at 12:21
  • $\begingroup$ You'll have to be a little more specific, please. I've tried this but it doesn't work. MyTicks2[min_, max_] := Function[ Module[{q, r}, {q, r} = QuotientRemainder[#, 60]; q = Mod[q, 24]; q = IntegerString[q, 10, 2]; r = IntegerString[r, 10, 2]; StringJoin[q, ":", r] ] ] /@ FindDivisions[{min, max, 60}, 5] $\endgroup$ – BruceH Feb 21 at 12:47
  • $\begingroup$ You're missing the &. $\endgroup$ – Szabolcs Feb 21 at 12:48
  • $\begingroup$ In the Function documentation, basic examples In[2] doesn't have an &. $\endgroup$ – BruceH Feb 21 at 12:50
  • $\begingroup$ Did you look at the answer I posted, which has a complete example? BTW the code you posted in the comment works fine. I misread it originally. $\endgroup$ – Szabolcs Feb 21 at 12:52
3
$\begingroup$

One way:

myTicks[min_, max_] :=
 Table[
  Module[{q, r},
   {q, r} = QuotientRemainder[x, 60];
   q = Mod[q, 24];
   q = IntegerString[q, 10, 2];
   r = IntegerString[r, 10, 2];
   StringJoin[q, ":", r]
   ],
  {x, FindDivisions[{min, max, 60}, 5]}
 ]

Another way:

myTicks[min_, max_] :=
 Module[{q, r},
    {q, r} = QuotientRemainder[#, 60];
    q = Mod[q, 24];
    q = IntegerString[q, 10, 2];
    r = IntegerString[r, 10, 2];
    StringJoin[q, ":", r]
  ] & /@ FindDivisions[{min, max, 60}, 5]

Look up Function for more details.

$\endgroup$
4
$\begingroup$

For the ultimate goal, you can use the internal function System`DateListPlotDump`DateTicks to generate the date ticks:

ClearAll[hourminuteTicks]
hourminuteTicks = MapAt[Round[#/60] &, 
  System`DateListPlotDump`DateTicks[60 {#, #2}, #3, {"Hour", ":", "Minute"}], {All, 1}] &;

Example:

hourminuteTicks[22*60, (3 + 24)*60, 5]

{{1320, "22:00"}, {1380, "23:00"}, {1440, "00:00"}, {1500, "01:00"}, {1560, "02:00"}, {1620, "03:00"}}

Take the last parts for the tick labels:

hourminuteTicks[22*60, (3 + 24)*60, 5][[All, 2]]

{"22:00", "23:00", "00:00", "01:00", "02:00", "03:00"}

$\endgroup$
0
$\begingroup$

Here's a compact, completely unreadable way to achieve your goal:

myTicks[min_, max_] := (StringJoin @@ {IntegerString[Mod[#1, 24], 10, 2], 
         ":", IntegerString[#2, 10, 2]}) & @@ 
     QuotientRemainder[#, 60] & /@ FindDivisions[{min, max, 60}, 5];

For readability, I think intermediate functions can be helpful, and if an intermediate function is only needed inside some larger function, you can define it locally:

myTicks[min_, max_] := Module[{f},
  minToHHMM[x_] := Module[
    {h, m},
    {h, m} = {Mod[#1, 24], #2} & @@ QuotientRemainder[x, 60];
    {h, m} = IntegerString[#, 10, 2] & /@ {h, m};
    StringJoin[#1, ":", #2] & @@ {h, m}
    ];
  minToHHMM /@ FindDivisions[{min, max, 60}, 5]
  ]
$\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.