Слишком много индексов для массива при использовании matplotlib

#python-3.x #numpy #matplotlib

#python-3.x #тупой #matplotlib

Вопрос:

Спасибо, что нашли время, чтобы прочитать этот вопрос.

Я пытаюсь построить круговые диаграммы в один ряд. Количество круговых диаграмм будет зависеть от возвращаемого результата.

 import matplotlib.pyplot as plt
import numpy as np

fig, axs = plt.subplots(1,len(to_plot_arr))
labels = ['Label1','Label2','Label3','Label4']

pos = 0
for scope in to_plot_arr:
    if data["summary"][scope]["Count"] > 0:
       pie_data = np.array(db_data)
       axs[0,pos].pie(pie_data,labels=labels)
       axs[0,pos].set_title(scope)
        
    pos  = 1

plt.show()
 

В коде db_data выглядит следующим образом: [12,75,46,29]
Когда я выполняю приведенный выше код, я получаю следующее сообщение об ошибке:

 Exception has occurred: IndexError
too many indices for array: array is 1-dimensional, but 2 were indexed
 

Я пытался найти, что может быть причиной этой проблемы, но просто не могу найти никакого решения. Я не уверен, что подразумевается под «но 2 были проиндексированы»

Я пробовал сгенерировать пирог cahrt с помощью :

 y = np.array(db_data)
plt.pie(y)
plt.show()
 

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

Надеюсь, вы сможете помочь мне в этом.

Еще раз спасибо.

Комментарии:

1. Не могли бы вы предоставить полную трассировку? или, по крайней мере, точная строка, в которой генерируется исключение. Спасибо

Ответ №1:

Обратите внимание, что axs созданный вами в строке 4 имеет форму (len(to_plot_arr),) , т.Е. Является 1D массивом, но в цикле в строках 11 и 12 вы предоставляете ему 2 индекса, которые сообщают интерпретатору, что это 2D массив, и конфликтуют с его фактической формой.

Вот исправление:

 import matplotlib.pyplot as plt
import numpy as np

fig, axs = plt.subplots(1,len(to_plot_arr))
labels = ['Label1','Label2','Label3','Label4']

pos = 0
for scope in to_plot_arr:
    if data["summary"][scope]["Count"] > 0:
       pie_data = np.array(db_data)
       axs[pos].pie(pie_data,labels=labels)
       axs[pos].set_title(scope)
        
    pos  = 1

plt.show()
 

Приветствия.

Комментарии:

1. Привет, Майкл, спасибо, что нашли время, чтобы прочитать мой вопрос и предоставить возможное решение. Я не совсем понял, что вы имели в виду под созданными мной осями, это 1D массив, потому что он определяется как «(1,len(to_plot_arr))». Таким образом, это должен быть 2D-массив. Я обнаружил, что сработало использование: «(2,len(to_plot_arr))». Когда я использовал это, диаграммы могли отображаться. Я отвечу на свой вопрос немного подробнее о том, как я нашел решение

Ответ №2:

Итак, я думаю, что это не технически, и отвечаю, потому что я до сих пор не знаю, что вызвало ошибку, но я нашел способ решить мою проблему, все еще достигая желаемого результата.

Во-первых, я понял, что когда я изменил: fig, axs = plt.subplots(1,len(to_plot_arr)) на: fig, axs = plt.subplots(2,len(to_plot_arr)) , фигура может быть нарисована. Итак, я продолжал пробовать с другими вариантами, такими как (1,2) , (2,1) , (1,3) и всегда обнаруживал, что если nrows`` or значение ncols« равно 1, появится ошибка.

К счастью, для моего варианта использования макет, который мне требовался, состоял из 2 строк, причем первая строка представляла собой один столбец, охватывающий 2, а нижняя строка — 2 столбца.

Итак, (2,2) очень хорошо подходите к моему варианту использования.

Затем я решил заставить верхнюю строку занимать 2 столбца и обнаружил, что это лучше всего сделать с GridSpec помощью Matplotlib. Пытаясь понять, как использовать GridSpec , я узнал, что использование add_subplot() будет лучшим маршрутом с большей гибкостью.

Итак, мой окончательный код выглядит примерно так:

 import matplotlib.pyplot as plt
import numpy as np
from matplotlib.gridspec import GridSpec

def make_chart():
    fig = plt.figure()
    fig.set_figheight(8)
    fig.set_figwidth(10)

    # Gridspec is used to specify the grid distribution of the figure
    gs = GridSpec(2,len(to_plot_arr),figure=fig)

    # This allows for the first row to span all the columns
    r1 = fig.add_subplot(gs[0,:])

    tbl = plt.table(
        cellText = summary_data,
        rowLabels = to_plot_arr,
        colLabels = config["Key3"],
        loc ='upper left',
        cellLoc='center'
    )
    tbl.set_fontsize(20)
    tbl.scale(1,3)    


    r1.axis('off')
    
    pos = 0
    for scope in to_plot_arr:
        if data["Key1"][scope][0] > 0:
            pie_data = np.array(data["Key2"][scope])

            # Add a chart at the specified position
            r2 = fig.add_subplot(gs[1,pos])
            r2.pie(pie_data, autopct=make_autopct(pie_data))
            r2.set_title(config["Key3"][scope])
        
        pos  = 1
    

    fig.suptitle(title, fontsize=24)
    plt.xticks([])
    plt.yticks([])
    fig.legend(labels,loc="center left",bbox_to_anchor=(0,0.25))   

    plt.savefig(savefile)

    return filename
 

Это была моя первая попытка использовать Matplotlib, кривая обучения была крутой, но с небольшим количеством пациентов и вниманием к документации я смог выполнить свою задачу. Я уверен, что есть лучшие способы сделать то, что я сделал. Если вы знаете лучший способ или знаете, как объяснить ошибку, с которой я столкнулся, пожалуйста, добавьте ответ на это.

Спасибо!