It's time to make a histogram

Python 3, 139

Generates histogram with numpy, takes on account the strange last column rule and prints.

from numpy import*
def f(l):
 h,_=histogram(l,'fd');h[-1]-=1
 for i in zip(*((max(h)-i)*' '+i*'▉'for i in append(h,1))):print(''.join(i))

05AB1E, 50 49 52 bytes

g.²òD>Ýs¹ZsWs\©-s/*®+v¹y.S>_O})¥ZUv'▉y×ðXy-׫S})øRJ»

Try it online!

Explanation

First we calculate k as the inclusive round up of log2 of the input length.

g.²ò

We then construct a list of upper bounds of the classes.
This is constructerd as range[0 .. k+1]*((max(input) - min(input))/k)+min(input) using the code:

D>Ýs¹ZsWs\©-s/*®+

Now we loop over this list counting the numbers of the input under these upper bounds. As we only want the numbers between each lower and upper bound we reduce this list by subtraction. Unfortunately due to a bug when comparing floats this becomes longer than it should be.

v¹y.S>_O})¥

Now that we have a list of the observation within each class we loop over these creating a matrix of the special char and fill them out with spaces so that each row in the matrix will have equal length.

v'▉y×ðXy-׫S})

This matrix has the staples of the histogram horizontally and we want them vertically. To remedy this, we transpose the matrix. This is the reason we filled the rows with spaces (as transpose need equal length lists). This gives us vertical bars starting from the top running down, so we reverse the order of the rows in the matrix. Now that we have the data in the correct order we print the matrix by joining the rows and joining the columns on newlines.

øRJ»


CJam, 72 71 bytes

l',-~$__,2b,\)\(:A\;-\d/:B;{AB+:A;_{A<},,_@>}h;]_:e>:M;{'▉*MSe[}%NM*a+z

Try it online!


l',-~$     e# read and sorts the list
__,2b,     e# find k
\)\(:A     e# find max and min (keep min as A)
\;-\d/:B;  e# find width (keep as B)
{          e# while entries remain
  AB+:A;   e#    find intervals upper bound
  _{A<},,  e#    count entries below bound
  _@>      e#    remove entries below bound
}h;        e# end while
]_:e>:M;   e# find maximum size
{'▉*MSe[}% e# convert to bars and pad columns
NM*a+z     e# add newlines and transpose to display upright