I'm trying to do a barchart of some negative and positive numbers. How can I show them all in Log space so that you can clearly see very big and very small exponent values?

mylist1 = {{"aa", -3.70*^-7}, {"bb",-1.81*^7}, {"cc",1.447*^6}, {"dd", -5.295*^8},{"ee",0}};
mylist2 = {{"aa", -3.70*^7}, {"bb",1.811*^7}, {"cc",1.447*^-6}, {"dd",0},{"ee",-5.29*^8}};

BarChart[{mylist1[[All, 2]], mylist2[[All, 2]]}]

enter image description here

Notice how those values that are positive but very small (e.g. "dd" in mylist2 seems to have the same value as "cc" in the same list).

Edit1: Please note that, although this question is related with another one as indicated by @shrx, my question focuses on maintaining the sign of negative numbers while still showing their exponents.

Edit2: I was able to find a work around for very small (<-1) or very large (>1) numbers through the following function:

posnegtest[val_] := 
 Which[val < -1, -Log10[-val], val > 1, Log10[val], -1 < val < 1, 
  If[val === 0, val, 
   Print[Style["WARNING! Value cannot be plotted like the others", 
     Red, Bold]]]]

but the issue of numbers between -1 and 1 remain (note, I'm ok with some values being exactly 0 though).


2 Answers 2


You can divide all of your data by 1/10th of the smallest absolute value before doing the log transform. This essentially scales the data to all have logs greater than one without adding a discontinuity on your axis. Then you can show the sign*log of positive and negative values from your original data on the same axis.

d = {-3.7*^-7, -1.81*^8, 1.5*^6, -5.3*^8, 0, -3.7*^7, 1.8*^7, 1.5*^-6,
   0, -5.3*^8};

scale = Min@Abs@DeleteCases[d, 0]/10

plotData = d/scale // Map[If[Abs@# > 0, Sign@# Log@Abs@#, 0] &]

ticks = 10.^Range[-7, 20] // 
   Join[-Reverse@#, #] & // {Sign@# Log@Abs[#/scale], #} & // 

BarChart[plotData, Ticks -> {Automatic, ticks}]

enter image description here


Is it sufficient to simply visualise the RealExponent - in this case, at least. I added some chart junk for added benefit.

BarChart[RealExponent[{mylist1[[All, 2]], mylist2[[All, 2]]}]/.-Infinity->0, 
 AxesOrigin -> {0, 0}, AxesLabel -> {"", "Exponent"}, 
 ChartLegends -> mylist1[[All, 1]], 
 ChartLabels -> {Placed[{Panel["mylist1"], Panel["mylist2"]}, Above], 

enter image description here

(edit by Sosi: this answer doesn't address one of the issues in the question, as discussed in the comments. This edit is to make that clear and also to let me change my downvote to an upvote since I learned something here. Thanks!)

  • $\begingroup$ I may misunderstanding, but the problem with this approach is that you cannot distinguish between positive and negative numbers can you? for instance, in mylist1 bb is negative whereas cc is positive, and yet they both show up very close to each other $\endgroup$
    – Sos
    Commented Aug 12, 2015 at 13:35
  • $\begingroup$ Also, sorry for the downvote, I really just wanted to cancel my upvote. I'll upvote as soon as you address this issue! Thanks $\endgroup$
    – Sos
    Commented Aug 12, 2015 at 13:39
  • $\begingroup$ @Sosi - no issue with downvote, I don't handle your requirement. MichaelHale's method is best and I've made a note of it for my own purposes. $\endgroup$ Commented Aug 12, 2015 at 13:49
  • $\begingroup$ @MartinJohnHadley still, your code is neat and taught me something, but I cant remove the downvote... :( $\endgroup$
    – Sos
    Commented Aug 12, 2015 at 15:57

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