3

This is my first program in python, so there could be things that are "funny" in my program. The program reads 3 columns from the files it finds in a given directory. Then computes the histogram for each file and the results are added to a two dimensional matrix in order to create something like a 2D-Hist.

My difficulty is in my 3rd plot, where I would like the y-axis data to be on a logarithmic scale and the data to be presented according to the scale. In addition I would like to remove "zero" entries from my input entries. I tried to use numpy.where(matrix) for that, but I don't know if that really does what I want...

Here is my code:

#!/usr/bin/python
# Filename: untitled.py
# encoding: utf-8

from __future__ import division
from matplotlib.colors import LogNorm
import matplotlib
import numpy as np
import matplotlib.pylab as plt
import os
import matplotlib.cm as cm

def main():

   dataFiles = [filename for filename in os.listdir(".") if (filename[-4:]==".log" and filename[0]!='.')]
   dataFiles.sort()

   p = []
   matrix1 = []
   matrix2 = []
   matrix3 = []

   for dataFile in dataFiles:
            p += [ eval(dataFile[11:16]) ]
            data = np.loadtxt(dataFile, skiprows=7)[:,1:4]

            matrix1 += [ data[:,0] ]
            matrix2 += [ data[:,1] ]
            matrix3 += [ data[:,2] ]

    matrixList = [matrix1, matrix2, matrix3]

    #make histograms out of the matrices
    matrix1Hist = [  np.histogram( matrixColumn, bins=30,  range=(np.min(np.where(matrix1 != 0)), np.max(matrix1)))[0]   for matrixColumn in matrix1 ]
    matrix2Hist = [  np.histogram( matrixColumn, bins=200, range=(np.min(np.where(matrix2 != 0)), np.max(matrix2)))[0]   for matrixColumn in matrix2 ]
    matrix3Hist = [  np.histogram( matrixColumn, bins=50,  range=(np.min(np.where(matrix3 != 0)), np.max(matrix3)))[0]   for matrixColumn in matrix3 ]

    # convert the matrixHistogramsto numpy arrays and swap axes
    matrix1Hist = np.array(matrix1Hist).transpose()
    matrix2Hist = np.array(matrix2Hist).transpose()
    matrix3Hist = np.array(matrix3Hist).transpose() 

    matrixHistList = [matrix1Hist, matrix2Hist, matrix3Hist]

    fig = plt.figure(0)
    fig.clf()

    for i,matrixHist in enumerate( [matrix1Hist, matrix2Hist, matrix3Hist] ):
            ax = fig.add_subplot(2, 2, i+1)
            ax.grid(True)
            ax.set_title('matrix'+str(i+1))
            if i < 2:
                   result = ax.imshow(matrixHist,
                                      cmap=cm.gist_yarg,
                                      origin='lower',
                                      aspect='auto', #automatically span matrix to available space
                                      interpolation='hanning',
                                      extent= [ p[0], p[-1], np.floor( np.min( matrixList[i])), np.ceil( np.max( matrixList[i])) ] ,
                                      )

            elif i == 2:
                    result = ax.imshow(matrixHist,
                                       cmap=cm.gist_yarg,
                                       origin='lower',
                                       aspect='auto', #automatically span matrix to available space
                                       interpolation='hanning',
                                       extent= [ p[0], p[-1], 1, np.log10(np.max( matrixList[i])) ] ,
                                       )


            ticks_at = [ 0 , abs(matrixHist).max()]
            fig.colorbar(result, ticks=ticks_at,format='%1.2g')


    plt.show()


if __name__ == '__main__':
    main()
Brendan
  • 18,771
  • 17
  • 83
  • 114
Eagle
  • 3,362
  • 5
  • 34
  • 46
  • Are you sure that this is your first Python program? Looking at you Python code it seems pretty well written, plus the `LogNorm` is imported but not used. Did I just do some homework? ;-) – Brendan Aug 06 '11 at 18:26
  • Possible duplicate of [Creating a log-linear plot in matplotlib using hist2d](https://stackoverflow.com/questions/29175093/creating-a-log-linear-plot-in-matplotlib-using-hist2d) – danijar May 11 '18 at 09:12

1 Answers1

4

For the first part of the question, you have the following options,

For the second part of your question - about filtering zero values from an array - try:

my_array = my_array[my_array != 0]

my_array != 0 creates a logical array of True and Falses which is then used in the slice. However this returns a one dimensional array which you probably don't want. To set the values to something else (and maintain the 2D shape), use the following (values are set to NaN) ...

my_array[my_array != 0] = np.NaN

Community
  • 1
  • 1
Brendan
  • 18,771
  • 17
  • 83
  • 114
  • 1
    thank for your answer. As i tried to find a solution to this log problem, i found as well the link you gave here, but the solution of `set_yscale('log')` is unfortunately not working with `imshow`. – Eagle Aug 06 '11 at 11:56
  • 2
    Ah ok, the 'histogram' is presented as a colour plot? In which case you can alter the `cmap` to one which scales logarithmically. I don't know how to do this off the top of my head but it is possible ... – Brendan Aug 06 '11 at 12:06