Как получить логарифмические оси для графика плотности с помощью matplotlib? - PullRequest
2 голосов
/ 07 октября 2011

Я пытаюсь сделать график плотности 2D (из некоторых данных моделирования) с помощью matplotlib.Мои данные x и y определены как log10 некоторых величин.Как я могу получить логарифмические оси (с небольшими галочками журнала)?

Вот пример моего кода:

import numpy as np
import matplotlib.pyplot as plt

Data = np.genfromtxt("data") # A 2-column data file
x = np.log10(Data[:,0])
y = np.log10(Data[:,1])

xmin = x.min()
xmax = x.max()
ymin = y.min()
ymax = y.max()

fig = plt.figure()
ax = fig.add_subplot(111)

hist = ax.hexbin(x,y,bins='log', gridsize=(30,30), cmap=cm.Reds)
ax.axis([xmin, xmax, ymin, ymax])

plt.savefig('plot.pdf')

Ответы [ 3 ]

4 голосов
/ 10 октября 2011

Из строки документации matplotlib.pyplot.hist выглядит, как будто есть аргумент 'log' для установки в 'True', если вы хотите масштабировать журнал по оси.

hist(x, bins=10, range=None, normed=False, cumulative=False,
     bottom=None, histtype='bar', align='mid',
     orientation='vertical', rwidth=None, log=False, **kwargs)

log:
If True, the histogram axis will be set to a log scale. If log is True and x is a 1D
array, empty bins will be filtered out and only the non-empty (n, bins, patches) will be
returned.

Существует также pyplotФункция .loglog для построения графика с масштабированием журнала по осям x и y.

3 голосов
/ 13 декабря 2011

Большое спасибо за предложения.

Ниже я присоединяюсь к собственному решению.Это вряд ли «минимальный рабочий пример», но я уже довольно много разобрал свой сценарий!

В двух словах, я использовал imshow для построения «изображения» (2D гистограмма с бревнами) и удаляю оси.Затем я рисую второй пустой (и прозрачный) график точно поверх первого графика, чтобы получить логарифмические оси, поскольку imshow, похоже, этого не позволяет.Довольно сложно, если вы спросите меня!

Мой код, вероятно, далеко не оптимален, так как я новичок в python и matplotlib ...

Кстати, я не использую hexbin по двум причинам: 1) Это слишком медленно, чтобы работать с очень большими файлами данных, такими как у меня.2) В версии, которую я использую, шестиугольники немного слишком велики, то есть они перекрываются, что приводит к появлению «пикселей» неправильной формы и размеров.Кроме того, я хочу иметь возможность записывать данные гистограммы в файл в текстовом формате.

#!/usr/bin/python

# How to get log axis with a 2D colormap (i.e. an "image") ??
#############################################################
#############################################################

import numpy as np
import matplotlib.cm as cm
import matplotlib.pyplot as plt
import math

# Data file containing 2D data in log-log coordinates.
# The format of the file is 3 columns : x y v
# where v is the value to plotted for coordinate (x,y)
# x and y are already log values
# For instance, this can be a 2D histogram with log bins.
input_file="histo2d.dat"

# Parameters to set space for the plot ("bounding box")
x1_bb, y1_bb, x2_bb, y2_bb = 0.125, 0.12, 0.8, 0.925

# Parameters to set space for colorbar
cb_fraction=0.15
cb_pad=0.05

# Return unique values from a sorted list, will be required later
def uniq(seq, idfun=None): 
    # order preserving
    if idfun is None:
        def idfun(x): return x
    seen = {}
    result = []
    for item in seq:
        marker = idfun(item)
        # in old Python versions:
        # if seen.has_key(marker)
        # but in new ones:
        if marker in seen: continue
        seen[marker] = 1
        result.append(item)
    return result

# Read data from file. The format of the file is 3 columns : x y v
# where v is the value to plotted for coordinate (x,y)

Data = np.genfromtxt(input_file)
x = Data[:,0]
y = Data[:,1]
v = Data[:,2]

# Determine x and y limits and resolution of data

x_uniq = np.array(uniq(np.sort(x)))
y_uniq = np.array(uniq(np.sort(y)))

x_resolution = x_uniq.size
y_resolution = y_uniq.size

x_interval_length = x_uniq[1]-x_uniq[0]
y_interval_length = y_uniq[1]-y_uniq[0]

xmin = x.min()
xmax = x.max()+0.5*x_interval_length
ymin = y.min()
ymax = y.max()+0.5*y_interval_length

# Reshape 1D data to turn it into a 2D "image"

v = v.reshape([x_resolution, y_resolution])
v = v[:,range(y_resolution-1,-1,-1)].transpose()

# Plot 2D "image" 
# ---------------

# I use imshow which only work with linear axes.
# We will have to change the axes later...

axis_lim=[xmin, xmax, ymin, ymax]

fig = plt.figure()
ax = fig.add_subplot(111)
extent = [xmin, xmax, ymin, ymax]
img = plt.imshow(v, extent=extent, interpolation='nearest', cmap=cm.Reds, aspect='auto')
ax.axis(axis_lim)

# Make space for the colorbar
x2_bb_eff = (x2_bb-(cb_fraction+cb_pad)*x1_bb)/(1.0-(cb_fraction+cb_pad))
ax.set_position([x1_bb, y1_bb, x2_bb_eff-x1_bb, y2_bb-y1_bb])
position = ax.get_position()

# Remove axis ticks so that we can put log ticks on top
ax.set_xticks([])
ax.set_yticks([])

# Add colorbar
cb = fig.colorbar(img,fraction=cb_fraction,pad=cb_pad)
cb.set_label('Value [unit]')

# Add logarithmic axes
# --------------------

# Empty plot on top of previous one. Only used to add log axes.
ax = fig.add_subplot(111,frameon=False)
ax.set_xscale('log')
ax.set_yscale('log')
plt.plot([])
ax.set_position([x1_bb, y1_bb, x2_bb-x1_bb, y2_bb-y1_bb])

axis_lim_log=map(lambda x: 10.**x, axis_lim)
ax.axis(axis_lim_log)

plt.grid(b=True, which='major', linewidth=1)
plt.ylabel('Some quantity [unit]')
plt.xlabel('Another quantity [unit]')

plt.show()
1 голос
/ 28 ноября 2011

Ответ от @gcalmettes относится к pyplot.hist.Сигнатура для pyplot.hexbin немного отличается:

hexbin(x, y, C = None, gridsize = 100, bins = None,
             xscale = 'linear', yscale = 'linear',
             cmap=None, norm=None, vmin=None, vmax=None, alpha=None, linewidths=None,
             edgecolors='none', reduce_C_function = np.mean, mincnt=None, marginals=True,
             **kwargs)

Вас интересует параметр xscale:

*xscale*: [ 'linear' | 'log' ]
    Use a linear or log10 scale on the horizontal axis.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...