Creating a log line graph in matplotlib using hist2d

I'm just wondering if this can be done. I tried setting the boxes explicitly using numpy logspace, and I also tried setting xscale to "log". None of these options work. Has anyone ever tried this?

I just want a 2d histogram with a log axis x and a linear axis y.

+6
source share
1 answer

The reason it does not work correctly is because plt.hist2d uses the pcolorfast method, which is much more efficient for large images, but does not support the log axis.

To have a 2D histogram that works correctly on the log axes, you need to do it yourself using np.histogram2d and ax.pcolor . However, this is only one additional line of code.

First, use exponentially spaced cells on the linear axis:

 import numpy as np import matplotlib.pyplot as plt x, y = np.random.random((2, 1000)) x = 10**x xbins = 10**np.linspace(0, 1, 10) ybins = np.linspace(0, 1, 10) fig, ax = plt.subplots() ax.hist2d(x, y, bins=(xbins, ybins)) plt.show() 

enter image description here

Good, all is well and good. Let's see what happens if we do the x axis we use the log scale:

 import numpy as np import matplotlib.pyplot as plt x, y = np.random.random((2, 1000)) x = 10**x xbins = 10**np.linspace(0, 1, 10) ybins = np.linspace(0, 1, 10) fig, ax = plt.subplots() ax.hist2d(x, y, bins=(xbins, ybins)) ax.set_xscale('log') # <-- Only difference from previous example plt.show() 

enter image description here

Note that log scaling seems to have been applied, but the color image (histogram) does not reflect it. The bunkers should seem square! This is not because the artist created by pcolorfast does not support the axis of the magazine.

To fix this, make a histogram using np.histogram2d (which plt.hist2d uses behind the scenes), and then build it using pcolormesh (or pcolor ), which supports the log axis:

 import numpy as np import matplotlib.pyplot as plt np.random.seed(1977) x, y = np.random.random((2, 1000)) x = 10**x xbins = 10**np.linspace(0, 1, 10) ybins = np.linspace(0, 1, 10) counts, _, _ = np.histogram2d(x, y, bins=(xbins, ybins)) fig, ax = plt.subplots() ax.pcolormesh(xbins, ybins, counts.T) ax.set_xscale('log') plt.show() 

(Note that here we must transpose counts , because pcolormesh expects the axes to be in order (Y, X).)

Now we get the result that we expect:

enter image description here

+12
source

Source: https://habr.com/ru/post/984065/


All Articles