Сюжеты динамического размера, добавленные в цикл - PullRequest
0 голосов
/ 12 июня 2019

Я очень плохо знаком с графикой в ​​python, и у меня возникают проблемы при создании подзаговора.

В настоящее время у меня есть цикл, который будет производить 2 массива, которые я затем назначаю столбцам Dataframe и использую df.plot() для графика.Это приводит к тому, что я получаю новый сюжет каждый раз в цикле.

Я хотел попробовать все на одном участке.Я создал объект figure вне моего цикла, и в цикле я пробовал приведенный ниже код.Я знаю, что мне нужно определить размер подзаговора, но проблема в том, что количество циклов определяется пользователем.Кроме того, что касается формы - если это 4 петли, 2x2 будет хорошо, но если это 25, я бы хотел попытаться максимально приблизить квадрат.Не уверен, что это выполнимо.

        ax = plt.subplot(i)
        ax.scatter(y_df['y_pred'], y_df['y_test'])

, но я продолжал получать следующую ошибку:

"трехзначное число, а не {}". Формат (args [0]))

ValueError: целочисленная спецификация подплота должна быть трехзначным числом, а не 1

Вот мой полный код.Я удалил много не относящихся к делу строк, чтобы было легче следить:

  fig = plt.figure()


    tscv = TimeSeriesSplit(n_splits=self.no_splits)
    for train_index, test_index in tqdm(tscv.split(X)):
        X_train, X_test = X.iloc[train_index], X.iloc[test_index]
        y_train, y_test = y.iloc[train_index], y.iloc[test_index]



        self.regressor.fit(X_train, y_train.ravel())

        # predict y values
        y_pred = self.regressor.predict(X_test)


        # plot y_pred vs y_test
        y_df = pd.DataFrame()
        y_pred = y_pred.reshape(len(y_pred), )
        y_test = y_test.reshape(len(y_test), )
        y_df['y_pred'] = y_pred
        y_df['y_test'] = y_test

        ax = plt.subplot(i)
        ax.scatter(y_df['y_pred'], y_df['y_test'])

1 Ответ

2 голосов
/ 13 июня 2019

add_subplot принимает три аргумента:

fig.add_subplot(nrows, ncols, index)

Если вы хотите обновить назначенное расположение подпункта (ов), вы можете использовать «change_geometry» на отдельных осях, который принимает те же три аргумента, например:

for i,ax in enumerate(fig.axes):
    if isinstance(ax,matplotlib.axes.SubplotBase):
        ax.change_geometry(len(fig.axes),1,i)

Я сделал небольшой пример, используя "change_geometry":

import matplotlib.pyplot as plt
from matplotlib.widgets import Slider
import numpy as np
import random


def run(val):
    n_axes = int(val)
    ax_names = random.sample(range(max_size),n_axes)

    i=0
    for ax_name in range(1,max_size):
        # Delete outdated axes
        if ax_name not in ax_names and ax_name in my_axes.keys():
            fig.delaxes(my_axes[ax_name])
            del my_axes[ax_name]
        if ax_name in ax_names:
            i+=1
            #Plot new data on new axes
            if ax_name not in my_axes.keys():
                print(i,n_axes)
                y = np.random.rand(x.shape[0])
                my_axes[ax_name] = ax = fig.add_subplot(n_axes,1,i)
                ax.plot(x,y)
            # Relocate "old" ax to new position
            else:
                my_axes[ax_name].change_geometry(n_axes,1,i)



fig = plt.figure()
my_axes = {}
x = np.linspace(0,1,100)
max_size=81

ax = plt.axes([0.1, 0.03, 0.8, 0.03], facecolor='#cccc00')
sNum = Slider(ax, '#plots', 1, max_size, valinit=1, valstep=1)
sNum.on_changed(run)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...