22

Given an an array of values, I want to plot a log log histogram of these values by their counts. I only know how to log the x values, but not the y values because they are not explicitly created in my program.

David Alber
  • 17,624
  • 6
  • 65
  • 71
user984923
  • 221
  • 1
  • 2
  • 4

2 Answers2

27

Check out the pyplot documentation.

  • pyplot.hist can "log" y axis for you with keyword argument log=True
  • pyplot.hist accepts bins keyword argument, but you have to "log" x axis yourself

For example:

#!/usr/bin/python
import numpy
from matplotlib import pyplot as plt

data = numpy.random.gumbel(2 ** 20, 2 ** 19, (1000, ))

bins = range(15, 25)
plt.xticks(bins, ["2^%s" % i for i in bins])
plt.hist(numpy.log2(data), log=True, bins=bins)
plt.show()

This will give you the actual counts of how how many elements fall into each bin, plotted on a log axis (which is what people usually mean by a log plot). I couldn't tell from your wording if you wanted this or the log of the count plotted on a linear axis.

Btw., bins don't even have to be spaced evenly.

Dima Tisnek
  • 11,241
  • 4
  • 68
  • 120
user670416
  • 736
  • 4
  • 12
  • 2
    To plot the log of the count of a linear axis is comparatively easier, and anyway both methods give the same graph. +1 for the key beginning. But I don't get what you do in the code : are you displaying fake exponential tick tags on what's really a linear x-scale ? – Nikana Reklawyks Jun 22 '15 at 19:03
0

Based on this solution we can define this simple method:

import numpy as np
import matplotlib.pyplot as plt

def plot_loghist(x, bins):
  hist, bins = np.histogram(x, bins=bins)
  logbins = np.logspace(np.log10(bins[0]),np.log10(bins[-1]),len(bins))
  plt.hist(x, bins=logbins)
  plt.xscale('log')
  plt.yscale('log')

And after that call like this:

plot_loghist(data, 10)

This is an example of the output for my data: enter image description here

Alireza Mazochi
  • 897
  • 1
  • 15
  • 22