NetworkX: построение графика в цикле for возвращает неправильный график

Я работаю с обычной сетью (сеткой), которую я создаю как:

import networkx as nx
N=100
def graph_creating(N):
    G=nx.grid_2d_graph(N,N)
    pos = dict( (n, n) for n in G.nodes() ) #Dictionary of all positions
return G, pos

У меня есть два способа повторения кода. В обоих случаях я удаляю узлы из сети и пытаюсь ее нарисовать. В зависимости от того, создаю ли я сеть изначально или внутри цикла, я получаю различное поведение, когда рисую ее.

Моя проблема: я хочу построить сетку после этапа 1 и после этапа 2, чтобы провести сравнение с неизмененной сеткой/графиком. Я не могу сделать это правильно, потому что:

  • Если исходная сетка создается вне цикла for, я правильно получаю первые графики, но последующие графики пусты, поскольку график никогда не восстанавливается до своего неизменного состояния;
  • Если исходная сетка создается внутри цикла for, я всегда получаю неизмененную сетку, как если бы удаление не повлияло на нее.

Куда еще нужно поместить блок построения графика, чтобы можно было построить график сразу после 1 и 2 этапа?

версия 1 график создается вне цикла for:

G, pos = graph_creating(N)
nodelist = G.nodes()
for counter in range(5):
    G1 = nodelist[2*counter:2*counter+1]
    G.remove_nodes_from(G1)
    nx.draw_networkx(G, pos = pos)
    figurename = 'file{0}.png'.format(counter)
    plt.savefig(figurename)

    G2=nodelist[2*counter+1:2*counter+2]
    G.remove_nodes_from(G2)
    nx.draw_networkx(G,pos=pos)
    #it's not clear from your original question if you save this figure or not

Результат: только первая итерация дает правильные графики. Более поздние графики пусты, поскольку график никогда не восстанавливается до своего неизмененного состояния.

версия 2 график создается внутри цикла for:

for counter in range(5):
    G, pos = graph_creating(N)
    nodelist = G.nodes()
    G1 = nodelist[2*counter:2*counter+1]
    G.remove_nodes_from(G1)
    nx.draw_networkx(G, pos = pos)
    figurename = 'file{0}.png'.format(counter)
    plt.savefig(figurename)

    G2=nodelist[2*counter+1:2*counter+2]
    G.remove_nodes_from(G2)
    nx.draw_networkx(G,pos=pos)
    #it's not clear from your original question if you save this figure or not

Результат: вызовы nx.draw_networkx приводят к построению неизменного графика для каждой итерации. Интересно, проблема в том, как я вызываю эту функцию, поскольку она всегда строит график без сбойных узлов. Почему у меня возникают проблемы с графикой?.


person FaCoffee    schedule 10.11.2015    source источник
comment
Я не уверен, что полностью понял это, но если ваша проблема в том, что исходный график изменен, почему бы просто не создать копию при входе в каждый цикл, чтобы исходный график не изменялся с помощью tmp_G = org_G.copy(). Кроме того, я не вижу разницы в вашем коде между ситуацией 1 и ситуацией 2.   -  person Abdallah Sobehy    schedule 10.11.2015
comment
Разница между сит 1 и 2 заключается в том, что на сит 1 график создается вне цикла, а на сит 2 — внутри. В первом случае я получаю ситуацию, когда граф берется целым и применяется csv файлов один за другим без обновления графа, что приводит к полному отказу сети после второй итерации. На этапе 2 график обновляется на каждой итерации, но он строится так, как будто сбоев не было (но сбои случаются).   -  person FaCoffee    schedule 10.11.2015
comment
Проблема в том, что при каждой итерации график должен строиться после этапа 1 и этапа 2. С новой итерацией график должен входить в цикл без изменений, чтобы я мог оценить, что происходит на этапах отказа. tmp_G = org_G.copy() возвращает NameError: name 'org_G' is not defined.   -  person FaCoffee    schedule 10.11.2015
comment
org_G — это просто имя, указывающее на то, что я имею в виду исходный граф. В вашем коде вы должны использовать tmp_G = G.copy() А затем применить изменения удаления узлов к tmp_G, а также построить его, чтобы увидеть изменения, и если вы хотите сравнить его с исходным использованием G   -  person Abdallah Sobehy    schedule 10.11.2015
comment
Я попытался объясниться в ответе   -  person Abdallah Sobehy    schedule 10.11.2015
comment
Я отредактировал ваш вопрос, чтобы попытаться создать MCVE. Пожалуйста, прочтите его, и если вы согласны с ним, оставьте как есть (хотя, вероятно, вам следует немного отредактировать его, чтобы убедиться, что он согласуется с вашим пболемом). Если вы не согласны, откатите его назад. Но самое главное, посмотрите, что я сделал, чтобы создать этот пример, потому что он будет полезен для получения хороших ответов в другом месте и меньшего количества голосов против.   -  person Joel    schedule 11.11.2015
comment
Если вы копируете и вставляете блок своего кода в вопрос, то каждая строка этого кода должна быть необходима для воспроизведения вашей проблемы, и ничего нельзя упростить. Если вы не считаете уместным использовать файлы .csv, включая шум, который мешает нам понять, что происходит. Если with_labels=False не является существенным для того, что вы наблюдаете, это просто шум. Актуально ли dpi=1000, node_size=10, bbox=tight? Если вы не знаете, вы недостаточно отладили, чтобы попросить нас потратить на это время. Если они не актуальны, удалите их.   -  person Joel    schedule 11.11.2015
comment
К тому времени, как вы сократите информацию до версии, которую я представил, вы, вероятно, поймете, что во второй версии исходный график не повторяется. Он строит график с удаленным G1. Если ваш код строит исходный график, это происходит из-за пропущенных линий, которые вы обнаружите при создании полного примера.   -  person Joel    schedule 11.11.2015
comment
Более общие комментарии по стилю кодирования. Я упростил способ обработки позиций. Это может быть полезно в вашем коде в целом, а может и нет. Это, безусловно, помогает нам прочитать и понять вашу проблему. - Вы должны определять функции. Например, создание графа не должно находиться в середине остального кода. Это должна быть его собственная функция, как я сделал. Это упрощает отладку, упрощает поддержку, упрощает объяснение и, возможно, более важно для исследователя — легче адаптироваться к новым вопросам.   -  person Joel    schedule 11.11.2015
comment
@Joel Большое спасибо за ваши усилия. Мне не удалось опубликовать MCVE из-за того, что мой код довольно длинный, я не привык с ним обращаться, а также сильно запутался. Кроме того, я настолько новичок в Python, что иногда мне трудно понять, как что-то визуализировать. Тогда еще раз, спасибо.   -  person FaCoffee    schedule 11.11.2015
comment
@Joel Но следует отметить одну вещь, как подчеркивается в ответе Абдаллы Собехи: я не получал правильного представления графика не из-за строк, которые не были включены в мой исходный пост, а из-за того, что я звонил nx.draw_network(G) , и эта строка по-прежнему относилась к оригинальной, неизмененной G, а не к измененным версиям, которые я намеревался изобразить. Я надеюсь, что сделал вещи более ясными.   -  person FaCoffee    schedule 11.11.2015


Ответы (1)


  • Сделайте свой блок создания графика вне цикла for.
  • Внутри цикла for создайте копию графика, используя tmp_G = G.copy()
  • при использовании draw_netwokx или remove_nodes_from используйте tmp_G вместо G
  • Если вы хотите сравнить измененные графики с исходными, вызовите функцию draw_networkx, используя график G.
person Abdallah Sobehy    schedule 10.11.2015
comment
Это сработало! Это должно иметь какое-то отношение к networkx, так как я знал, что исходный график должен быть создан вне цикла. В частности, я думаю, что nx.draw_network не очень гибкий: при изменении G он должен отображать его так, как он есть, например. он должен следовать изменениям G. Но похоже, что это не так. Спасибо, в любом случае! - person FaCoffee; 10.11.2015
comment
@FrancescoCastellani по мере изменения G должен отображать его так, как он есть, например. он должен следовать за изменениями G... Что вы хотите этим сказать? Каждый раз, когда вы говорите ему рисовать G, он рисует текущую версию G. - person Joel; 10.11.2015
comment
Ну, если бы это было так, мне не нужно было бы делать копию. Это интересный момент: почему поток скрипта работает, если я использую H=G.copy()? И почему это не так, если я использую только G? - person FaCoffee; 10.11.2015
comment
потому что вы вносите изменения в G в более старой версии, поэтому вы больше не можете получить неизмененную версию. Итак, вы создаете временную копию, чтобы свободно манипулировать - person Abdallah Sobehy; 10.11.2015
comment
@FrancescoCastellani Ну, если бы это было так, мне не нужно было бы делать его копию .. Нет. Вы неправильно понимаете, о чем просите. Он рисует текущую версию G. Вы много изменяли G - каждый раз в цикле вы изменяли его все больше. Копия, которую помог вам создать Абдалла, позволяет вам оставить оригинал G в покое, чтобы вы каждый раз начинали заново. - person Joel; 10.11.2015
comment
Да, и это то, что я хотел. Я имел в виду идею, что G был обновлен, переходя от неизмененного статуса к этапу 1, а затем к этапу 2... - person FaCoffee; 10.11.2015