2016-10-08 5 views
1

У меня возникли проблемы с созданием полярных гистограмм с осью симлога. Однако это происходит только при отрицательных значениях r. Что я могу сделать, чтобы исправить это?С помощью matplotlib, как я могу создать двумерную гистограмму с полярной проекцией и осью симлога r?

Я включил минимальный пример, который отображает 5 графиков. Участок 4 - тот, который не работает (средний ряд справа). Сюжет 5 показывает, что он работает с положительными числами.

Вот результат:

enter image description here

Вот код:

import numpy as np 
import matplotlib.pyplot as plt 
from matplotlib import cm 
from matplotlib.scale import SymmetricalLogTransform 


MIN_BINS = 500 
MAX_BINS = 1000 
# utility function for making bins of correct size 
def get_bins(min_val, max_val, scaling): 
    w = 1 + max(MIN_BINS, min(MAX_BINS, abs(min_val - max_val) + 1)) 

    if scaling == 'log': 
     return np.logspace(np.log10(min_val), np.log10(max_val), w) 
    elif scaling == 'symlog': 
     tr = SymmetricalLogTransform(base=10, linthresh=1, linscale=1) 

     ss = tr.transform([min_val, max_val]) 

     ls = tr.inverted().transform(np.linspace(*ss, num=w)) 
     return ls 
    else:# linear 
     return np.linspace(min_val, max_val, w) 




TESTS = [1,2,3,4,5] 

plt.figure(figsize=(12,18)) 
plot_pos = 320 
for TEST in TESTS: 
    plot_pos += 1 

    if TEST == 1: 
     NEG = True 
     YSCALE = 'linear' 
     PROJECTION = None 

    if TEST == 2: 
     NEG = True 
     YSCALE = 'symlog' 
     PROJECTION = None 


    if TEST == 3: 
     NEG = True 
     YSCALE = 'linear' 
     PROJECTION = 'polar' 

    # This is what I want to work 
    if TEST == 4: 
     NEG = True 
     YSCALE = 'symlog' 
     PROJECTION = 'polar' 

    # However, remove the negative numbers and it seems to work 
    if TEST == 5: 
     NEG = False 
     YSCALE = 'symlog' 
     PROJECTION = 'polar' 



    sample_size = 100000 
    xs = np.pi * np.linspace(0.0, 2.0, sample_size) 
    ys = 20 * np.random.random(sample_size) 

    if NEG: 
     ys -= 10 

    ax = plt.subplot(plot_pos, projection=PROJECTION) 

    ax.set_title('Neg/Scale/Proj.:%s,%s,%s' % (NEG, YSCALE, PROJECTION)) 

    min_y = np.min(ys) 
    max_y = np.max(ys) 
    min_x = np.min(xs) 
    max_x = np.max(xs) 

    x_bins = get_bins(min_x, max_x, 'linear') 
    y_bins = get_bins(min_y, max_y, YSCALE) 

    hist, xedges, yedges = np.histogram2d(
     xs, 
     ys, 
     bins=[x_bins, y_bins] 
    ) 

    X, Y = np.meshgrid(xedges, yedges) 

    ax.pcolormesh(
     X, Y, 
     hist.T, 
     cmap=cm.gray_r, 
    ) 

    if PROJECTION == 'polar': 
     ax.set_rscale(YSCALE) 

     ax.set_rmax(max_y) 
     ax.set_rmin(min_y) 
    else: 
     ax.set_ylim([min_y, max_y]) 

     ax.set_yscale(YSCALE) 

    ax.grid(True) 

plt.savefig('polar_example.png') 
+1

Для тех, кто интересно, что такое «symlog» шкала есть сведения о симметричных логарифмических шкал в [этот вопрос] (Http: // StackOverflow. ком/вопросы/3305865/что-это-разностной-между-срубы и-symlog). Они очень полезны. – Annan

+0

Да, извините, я понял, оставив комментарий :) Оказывается, не должно быть умной задницей после 2 утра ... Я просто не удалял свой комментарий достаточно быстро;) Извините. –

+0

@AndrasDeak Нет проблем :) Они не так распространены, я недавно узнал о них. – Annan

ответ

1

Это может быть ошибка в Matplotlib, к сожалению, полярные участки имеют несколько scaling issues и might have to go through some major revisions in the future.

Я подозреваю, что проблема в этом, для проблемных четвертого polar - symlog осей:

>>> ax.get_rmin() 
-9.9998049982336408 

>>> ax.get_rmax() 
9.9999564676741315 

Отрицательные радиусы присутствуют, так как symlog готов справиться с ними. Однако у matplotlib были некоторые проблемы, отображающие эти значения, и corresponding behaviour even changed in the past. Я думаю, что единственная проблема в том, что отрицательные радиальные пределы, принятые во время вызова ax.set_rmin(), интерпретируются как отраженные положительные значения. Вот ваш тест при изменении радиального случая к

if PROJECTION == 'polar': 
    ax.set_rscale(YSCALE) 

    ax.set_rmax(max_y) 
    ax.set_rmin(max(0,min_y)) # change here 

fixed result

 Смежные вопросы

  • Нет связанных вопросов^_^