цикл над 2-м сюжетом, как если бы это был 1-D

Я пытаюсь построить много данных, используя подзаголовки, и у меня НЕ проблемы, но мне интересно, есть ли для этого удобный метод.

ниже приведен пример кода.

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

quantities=["sam_mvir","mvir","rvir","rs","vrms","vmax"
,"jx","jy","jz","spin","m200b","m200c","m500c","m2500c"
,"xoff","voff","btoc","ctoa","ax","ay","az"]

# len(quantities) = 21, just to make the second loop expression 
# shorter in this post.

ncol = 5
nrow = math.ceil(21 / ncol)

fig, axes = plt.subplots(nrows = nrow, ncols=ncol, figsize=(8,6))

for i in range(nrow):
    for j in range(((21-i*5)>5)*5 + ((21-i*5)<5)*(21%5)):
        axes[i, j].plot(tree[quantities[i*ncol + j]]) 
        axes[i, j].set_title(quantities[i*ncol + j])

Этот код перебирает двумерный массив подграфиков и останавливается на 21-м графике, оставляя 4 пустых панели. Мой вопрос в том, есть ли встроенный метод для выполнения этой задачи? Например, создайте массив 2D-подзаголовков и «сгладьте» массив в 1D, а затем выполните цикл по массиву 1D от 0 до 20.

Выражение во втором диапазоне() очень уродливое. Я не думаю, что буду использовать этот код. Я думаю, что тривиальный способ - подсчитать количество участков и сломать, если количество > 21. Но мне просто интересно, есть ли лучший (или причудливый) способ.


person Hoseung Choi    schedule 21.01.2015    source источник


Ответы (2)


Вместо того, чтобы создавать свои подзаголовки заранее, используя plt.subplots, просто создавайте их по мере использования, используя plt.subplot(nrows, ncols, number). Небольшой пример ниже показывает, как это сделать. Он создал массив графиков 3x3 и построил только первые 6.

import numpy as np
import matplotlib.pyplot as plt

nrows, ncols = 3, 3

x = np.linspace(0,10,100)

fig = plt.figure()    
for i in range(1,7):
    ax = fig.add_subplot(nrows, ncols, i)
    ax.plot(x, x**i)

plt.show()

Пример

Конечно, вы можете заполнить последние три, выполнив plt.subplot(nrows, ncols, i), но не вызывая там никаких графиков (если вы этого хотите).

import numpy as np
import matplotlib.pyplot as plt

nrows, ncols = 3, 3

x = np.linspace(0,10,100)

fig = plt.figure()    
for i in range(1,10):
    ax = fig.add_subplot(nrows, ncols, i)
    if i < 7:
        ax.plot(x, x**i)

plt.show()

Пример 2

Вам также может понравиться внешний вид GridSpec.

person Ffisegydd    schedule 21.01.2015
comment
Ах..... Вот почему я смог найти что-нибудь, что, кажется, отвечает на мой вопрос...! Вопрос был просто некорректен. Большое спасибо! Это было быстро. - person Hoseung Choi; 21.01.2015
comment
Если вы собираетесь сделать это таким образом, вы должны по крайней мере использовать fig.add_subplot, чтобы убедиться, что конечный автомат не сопротивляется. - person tacaswell; 22.01.2015

subplots возвращает ndarray объектов осей, вы можете просто сгладить или распутать его:

fig, axes = plt.subplots(nrows = nrow, ncols=ncol, figsize=(8,6))
for ax in axes.flatten()[:20]:
    # do stuff to ax
person tacaswell    schedule 22.01.2015