Проблемы с matplotlib при построении записанных данных и установке их границ x / y

Я использую графики журнала в matplotlib примерно следующим образом.

plt.scatter(x, y)

# use log scales
plt.gca().set_xscale('log')
plt.gca().set_yscale('log')

# set x,y limits
plt.xlim([-1, 3])
plt.ylim([-1, 3])

Первая проблема заключается в том, что без ограничений x, y matplotlib устанавливает такие масштабы, что большая часть данных не видна - по какой-то причине он не использует минимальные и максимальные значения по измерениям x и y, поэтому сюжет по умолчанию крайне вводит в заблуждение.

когда я устанавливаю пределы вручную с помощью plt.xlim, plt.ylim, которые я интерпретирую как от -1 до 3 в единицах log10 (т.е. от 1/10 до 3000), я получаю график, подобный приведенному. enter image description here

Названия осей здесь не имеют смысла: они идут от 10 ^ 1 до 10 ^ 3. Что здесь происходит?

Я привожу более подробный пример ниже, который показывает все эти проблемы с данными:

import matplotlib
import matplotlib.pyplot as plt
from numpy import *

x = array([58, 0, 20, 2, 2, 0, 12, 17, 16, 6, 257, 0, 0, 0, 0, 1, 0, 13, 25, 9, 13, 94, 0, 0, 2, 42, 83, 0, 0, 157, 27, 1, 80, 0, 0, 0, 0, 2, 0, 41, 0, 4, 0, 10, 1, 4, 63, 6, 0, 31, 3, 5, 0, 61, 2, 0, 0, 0, 17, 52, 46, 15, 67, 20, 0, 0, 20, 39, 0, 31, 0, 0, 0, 0, 116, 0, 0, 0, 11, 39, 0, 17, 0, 59, 1, 0, 0, 2, 7, 0, 66, 14, 1, 19, 0, 101, 104, 228, 0, 31])

y = array([60, 0, 9, 1, 3, 0, 13, 9, 11, 7, 177, 0, 0, 0, 0, 1, 0, 12, 31, 10, 14, 80, 0, 0, 2, 30, 70, 0, 0, 202, 26, 1, 96, 0, 0, 0, 0, 1, 0, 43, 0, 6, 0, 9, 1, 3, 32, 6, 0, 20, 1, 2, 0, 52, 1, 0, 0, 0, 26, 37, 44, 13, 74, 15, 0, 0, 24, 36, 0, 22, 0, 0, 0, 0, 75, 0, 0, 0, 9, 40, 0, 14, 0, 51, 2, 0, 0, 1, 9, 0, 59, 9, 0, 23, 0, 80, 81, 158, 0, 27])

c = 0.01

plt.figure(figsize=(5,3))
s = plt.subplot(1, 3, 1)
plt.scatter(x + c, y + c)
plt.title('Unlogged')
s = plt.subplot(1, 3, 2)
plt.scatter(x + c, y + c)
plt.gca().set_xscale('log', basex=2)
plt.gca().set_yscale('log', basey=2)
plt.title('Logged')
s = plt.subplot(1, 3, 3)
plt.scatter(x + c, y + c)
plt.gca().set_xscale('log', basex=2)
plt.gca().set_yscale('log', basey=2)
plt.xlim([-2, 20])
plt.ylim([-2, 20])
plt.title('Logged with wrong xlim/ylim')
plt.savefig('test.png')

Это дает график ниже:

enter image description here

На первом подзаголовке слева у нас есть необработанные незарегистрированные данные. Во-вторых, у нас есть представление по умолчанию для зарегистрированных значений. В-третьих, мы зарегистрировали значения с указанными ограничениями x / y. У меня следующие вопросы:

  1. почему границы x / y по умолчанию для диаграммы рассеяния неверны? в руководстве говорится, что предполагается использовать в данных минимальные и максимальные значения, но здесь явно не так. Он выбрал значения, которые скрывают подавляющее большинство данных.

  2. почему, когда я сам устанавливаю границы на третьем графике рассеяния слева, он меняет порядок меток на обратный? Показано 2 ^ 8 перед 2 ^ 5? Это очень сбивает с толку.

  3. наконец, как я могу получить это, чтобы графики не сжимались таким образом по умолчанию с использованием подзаголовков? Я хотел, чтобы эти точечные диаграммы были квадратными.

РЕДАКТИРОВАТЬ: Спасибо Джо и Хонку за ответ. Если я попытаюсь настроить подзаголовки таким образом, чтобы они были квадратными:

plt.figure(figsize=(5,3), dpi=10)
s = plt.subplot(1, 2, 1, adjustable='box', aspect='equal')
plt.scatter(x + c, y + c)
plt.title('Unlogged')
s = plt.subplot(1, 2, 2, adjustable='box', aspect='equal')
plt.scatter(x + c, y + c)
plt.gca().set_xscale('log', basex=2)
plt.gca().set_yscale('log', basey=2)
plt.title('Logged')

Я получаю следующий результат:

enter image description here

Как я могу сделать так, чтобы каждый график был квадратным и выровнен друг с другом? Это должна быть просто квадратная сетка, все одинаковые размеры ...

РЕДАКТИРОВАТЬ 2:

Чтобы внести что-то обратно, вот как можно взять эти графики log 2 и заставить оси появиться с их неэкспонентной нотацией :

import matplotlib

from matplotlib.ticker import FuncFormatter

def log_2_product(x, pos):
    return "%.2f" %(x)

c = 0.01
plt.figure(figsize=(10,5), dpi=100)
s1 = plt.subplot(1, 2, 1, adjustable='box', aspect='equal')
plt.scatter(x + c, y + c)
plt.title('Unlogged')
plotting.axes_square(s1)
s2 = plt.subplot(1, 2, 2, adjustable='box', aspect='equal')
min_x, max_x = min(x + c), max(x + c)
min_y, max_y = min(y + c), max(y + c)
plotting.axes_square(s2)
plt.xlim([min_x, max_x])
plt.ylim([min_y, max_y])
plt.gca().set_xscale('log', basex=2)
plt.gca().set_yscale('log', basey=2)
plt.scatter(x + c, y + c)
formatter = FuncFormatter(log_2_product)
s2.xaxis.set_major_formatter(formatter)
s2.yaxis.set_major_formatter(formatter)

plt.title('Logged')
plt.savefig('test.png')

спасибо за вашу помощь.

9
задан 17 January 2012 в 05:58
поделиться