2017-02-07 12 views
0

別のdbに格納された情報に基づいて、各Classオブジェクトに関連する円グラフを作成するために、models.py内のDjangoクラスオブジェクトを反復しようとしています。manage.pyシェルでDjangoクラスオブジェクトを反復処理しますか?

コマンドプロンプトでシェルを実行して、I入力:

from file.models import Person, piemaker 
    for i in Person.objects.all(): 
    i.piegraph = i.pgraph() 
    i.save() 

その際、私は私のPersonクラスの各オブジェクトのためのPNGファイルとしてpiegraphを取得します。しかし、グラフが1つのグラフとして飛び出すのではなく、他のグラフの上に横たわっているように見えます。同じようなラベルが繰り返され、互いの上に重ねられます。

私はこれが壊れているところで立ち往生していますが、私の推測は私のforループの中にありますか? piemaker関数を1つのクラスオブジェクトだけで実行すると、素晴らしいpiegraphを含む正しいpngファイルが吐き出されます。

from file.models import Person, piemaker 
    a = Person.objects.get(name='name') 
    a.piegraph = a.pgraph() 
    a.save() 

私はこれを2日間無駄なく使用しています。どんな助けもありがとう。

#!python3 

###import statements#### 
from django.db import models 
import pandas as pd 
import sqlite3 
import re 
import matplotlib.pyplot as plt 

##global start and end variables#### 
start = '2015-01-01' 
end = '2016-01-01' 

####fux for making, saving dynamic piegraph file 
def piemaker(pietag): 
     try: 
####file to save as#### 
      filename = 'C:\\users\\user\\PycharmProjects\\Test2\\media_cdn\\pie-' + pietag + start + end+'.png' 
     ####file name to return for Django FileField#### 
     file = 'pie-' + pietag + start + end+'.png' 

     ###read my db which is external to Django to get parameters for pie graph 
     df = pd.read_sql_query("SELECT * FROM db WHERE " + pietag + " = 1 AND post_date >= '" + str(start) + "' AND post_date <= '" + str(end) + "'", conn) 
     df.drop(['sets'], axis=1, inplace=True) 
     df = df.astype(int) 
     df = df.loc[:, (df !=0).any(axis=0)] 

     sums = df.sum() 
     sums.sort_values(ascending=False, inplace=True) 
     other = 0 
     for i in sums[3:]: 
      other += i 
      sums['other'] = other 
     sums.sort_values(ascending=False, inplace=True) 
     pie = sums.drop(sums[4:].keys()) 
     plt.title('Texts/tags associated with ' + pietag + ' between: ' + start + '-' + end) 
     plt.pie(pie,labels=pie.keys(), explode= (0,.15,0,0), startangle=90, autopct=make_autopct(pie)) 
     plt.savefig(filename, bbox_inches='tight') 
     return file 
    except ValueError: 
      return 'nothing here' 

class Person(models.Model): 


    def __str__(self): 
     return self.name 

    @property 
    def tag(self): 
     return self.name.lower().replace(' ', '_') 

    def pgraph(self): 
     return(piemaker(self.tag)) 

    name = models.CharField(max_length=50, unique=True) 
    tags = models.TextField(default='tag') 
    piegraph = models.FileField(null=True, blank=True) 

答えて

0

私はあなたの問題はあなたがmatplotlibのインタラクティブバージョンを使用しようとしているということだと思います。これは非常に奇妙な結果に終ります。代わりにFigureオブジェクトを使用して、次のような操作を行う必要があります。

from matplotlib.figure import Figure 

def graphic(request): 
     # other code goes here 
     fig=Figure() 
     fig1=fig.add_subplot(1,1,1) 
     fig1.pie((pie,labels=pie.keys(), explode= (0,.15,0,0), startangle=90, autopct=make_autopct(pie))) 
     fig.savefig(filename) 
     return filename 
+0

これは、エラーが発生した場所、つまり対話的なプロットを使用していた場所を正しく指摘してくれたときに役立ちました。それにもかかわらず、私はこれを少し違って解決することにしました。追加された行はplt.savefig(...)の後に来たので、図をクリアするためにplt.clf()を追加して、各繰り返しごとに新しいものが作成されるようにしました。 – DTracer

+1

私の経験から、djangoでmatplotlibのインタラクティブバージョンを使用すると、この場合には使用されないため、多くの望ましくない結果(サーバフリーズなど)が発生します。だから私はこれを行うことをお勧めしません。 –