Skip to content

Commit

Permalink
better plotting with defaults
Browse files Browse the repository at this point in the history
Just have one plot function that displays: empty plot if no data, one or the other with data, and both if both have data. simpler, cleaner, smaller.
  • Loading branch information
jacksonwalters committed Feb 28, 2021
1 parent fdf89e0 commit 6de2010
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 211 deletions.
217 changes: 30 additions & 187 deletions flask/plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,210 +7,53 @@
import time, os

CURRENT_YEAR=2021
MIN_YEAR = 2000
NEUTRAL = 0 #the line deciding which side of the issue
IMG_PATH='./static/images/'

#create plot of only SCOTUS opinion polarity given {YEAR:POLARITY}
def scotus_plot(sc_polarity,title="ISSUE"):

#SCOTUS years, liberal v. conservative sentiment
x_sc=list(sc_polarity.keys())
y_sc=list(sc_polarity.values())

#get basic stats
slope, intercept, r_value, p_value, std_err = stats.linregress(x_sc,y_sc)

#degree 1 model for SC
sc_deg1=np.polyfit(x_sc,y_sc,1)
g1 = np.poly1d(sc_deg1)
#degree 3 model for SC
sc_deg3=np.polyfit(x_sc,y_sc,3)
g3 = np.poly1d(sc_deg3)

#find paradigm shift for SC.
#assuming one point of intersection.
#this is guaranteed for a linear fit.
p_shift_sc=opt.fsolve(g1-NEUTRAL,2000)

#create figure, axes
fig = plt.figure()
ax = fig.add_subplot(111)

#supreme court decisions
sc_scatter=ax.scatter(x_sc,y_sc,c='r',marker="+",label='Supreme Court',vmin=-1, vmax=1)
#model for SC data
ax.plot(x_sc,g1(x_sc),'-r')

#include horizontal neutral opinion line
#purple='#551A8B'
ax.axhline(y=NEUTRAL,color='k')
#include vertical lines at crossover moments

ax.plot([p_shift_sc], [NEUTRAL], marker='|', markersize=7, color="black")

ax.legend()
plt.xlabel('Time (year)')
plt.ylabel('Polarity')
plt.title('SCOTUS Opinion Polarity on ' + title)
plt.grid(True)
plt.yticks(np.arange(-1,2,1),["Conservative","Neutral","Liberal"]) #y-ticks are -1, 0, +1

#fig.colorbar(sc_scatter)

#min_yr=min(x_sc)
min_yr=min(x_sc)
plt.axis([min_yr-2, CURRENT_YEAR, -1.1, 1.1])

#remove previous plot and save new one with title corresponding to keywords
plot_filename = "sc_v_po_" + title + ".png"
for filename in os.listdir('./static/images/'):
if filename.startswith('sc_v_po_'):
os.remove('./static/images/' + filename)
plt.savefig(IMG_PATH+plot_filename, bbox_inches='tight')
#plt.show()
plt.gcf().clear()

return plot_filename

#create plot of public opinion polarity given {YEAR:POLARITY}
def public_plot(po_polarity,title="ISSUE"):

#PUBLIC OPINION
x_po=list(po_polarity.keys())
y_po=list(po_polarity.values())

#get basic stats
slope, intercept, r_value, p_value, std_err = stats.linregress(x_po,y_po)

#degree 1 model for PO
po_deg1=np.polyfit(x_po,y_po,1)
f1 = np.poly1d(po_deg1)
#degree 3 model for PO
po_deg3=np.polyfit(x_po,y_po,3)
f3 = np.poly1d(po_deg3)

#find paradigm shift for PO.
#assuming one point of intersectionself.
#this is guaranteed for a linear fit.
p_shift_po=opt.fsolve(f1-NEUTRAL,2000)

#create figure, axes
fig = plt.figure()
ax = fig.add_subplot(111)


#average public opinion on issue
ax.scatter(x_po,y_po,c='b',marker="x",label='Public Opinion',vmin=-1, vmax=1)
#model for PO data
ax.plot(x_po,f1(x_po),'-b')

#include horizontal neutral opinion line
#purple='#551A8B'
ax.axhline(y=NEUTRAL,color='k')
#include vertical lines at paradigm shift moments
ax.plot([p_shift_po], [NEUTRAL], marker='|', markersize=7, color="black")

ax.legend()
plt.xlabel('Time (year)')
plt.ylabel('Polarity')
plt.title('[Public Opinion TBD] on ' + title)
plt.grid(True)
plt.yticks(np.arange(-1,2,1),["Conservative","Neutral","Liberal"]) #y-ticks are -1, 0, +1

#fig.colorbar(sc_scatter)

#min_yr=min(x_po)
min_yr=min(x_po)
plt.axis([min_yr-2, CURRENT_YEAR, -1.1, 1.1])

#remove previous plot and save new one with title corresponding to keywords
plot_filename = "sc_v_po_" + title + ".png"
for filename in os.listdir('./static/images/'):
if filename.startswith('sc_v_po_'):
os.remove('./static/images/' + filename)
plt.savefig(IMG_PATH+plot_filename, bbox_inches='tight')
#plt.show()
plt.gcf().clear()

return plot_filename

#create plot of both SCOTUS & public opinion polarity given {YEAR:POLARITY}
def scotus_v_public_plot(sc_polarity,po_polarity,title="ISSUE"):

#PUBLIC OPINION
x_po=list(po_polarity.keys())
y_po=list(po_polarity.values())

#get basic stats
slope, intercept, r_value, p_value, std_err = stats.linregress(x_po,y_po)

#degree 1 model for PO
po_deg1=np.polyfit(x_po,y_po,1)
f1 = np.poly1d(po_deg1)
#degree 3 model for PO
po_deg3=np.polyfit(x_po,y_po,3)
f3 = np.poly1d(po_deg3)

#find paradigm shift for PO.
#assuming one point of intersectionself.
#this is guaranteed for a linear fit.
p_shift_po=opt.fsolve(f1-NEUTRAL,2000)

#SCOTUS years, liberal v. conservative sentiment
x_sc=list(sc_polarity.keys())
y_sc=list(sc_polarity.values())

#get basic stats
slope, intercept, r_value, p_value, std_err = stats.linregress(x_sc,y_sc)

#degree 1 model for SC
sc_deg1=np.polyfit(x_sc,y_sc,1)
g1 = np.poly1d(sc_deg1)
#degree 3 model for SC
sc_deg3=np.polyfit(x_sc,y_sc,3)
g3 = np.poly1d(sc_deg3)

#find paradigm shift for SC.
#assuming one point of intersection.
#this is guaranteed for a linear fit.
p_shift_sc=opt.fsolve(g1-NEUTRAL,2000)
def scotus_v_public_plot(sc_polarity=None,po_polarity=None,title="ISSUE"):

#create figure, axes
fig = plt.figure()
ax = fig.add_subplot(111)

min_year = MIN_YEAR #minimum year for t-axis on plot

#average public opinion on issue
ax.scatter(x_po,y_po,c='b',marker="x",label='Public Opinion',vmin=-1, vmax=1)
#model for PO data
ax.plot(x_po,f1(x_po),'-b')

#supreme court decisions
sc_scatter=ax.scatter(x_sc,y_sc,c='r',marker="+",label='Supreme Court',vmin=-1, vmax=1)
#model for SC data
ax.plot(x_sc,g1(x_sc),'-r')

#include horizontal neutral opinion line
#purple='#551A8B'
ax.axhline(y=NEUTRAL,color='k')
#include vertical lines at paradigm shift moments

ax.plot([p_shift_po], [NEUTRAL], marker='|', markersize=7, color="black")

ax.plot([p_shift_sc], [NEUTRAL], marker='|', markersize=7, color="black")
#PUBLIC OPINION
if po_polarity is not None:
x_po=list(po_polarity.keys()) #get public opinion years
y_po=list(po_polarity.values()) #get public opinion polarity values
min_year = min(x_po+[min_year]) #update minimum year from public opinion data
slope, intercept, r_value, p_value, std_err = stats.linregress(x_po,y_po) #get basic stats
po_deg1=np.polyfit(x_po,y_po,1); f1 = np.poly1d(po_deg1) #degree 1 model for PO
p_shift_po=opt.fsolve(f1-NEUTRAL,2000) #find "paradigm shift" for PO. assuming one point of intersectionself. this is guaranteed for a linear fit.
ax.plot([p_shift_po], [NEUTRAL], marker='|', markersize=7, color="black") #include vertical lines at crossover moments
ax.scatter(x_po,y_po,c='b',marker="x",label='Public Opinion',vmin=-1, vmax=1) #average public opinion on issue
ax.plot(x_po,f1(x_po),'-b') #plot model for PO data

#SCOTUS OPINIONS
if sc_polarity is not None:
x_sc=list(sc_polarity.keys()) #get scotus years
y_sc=list(sc_polarity.values()) #get scotus polarity values
min_year = min(x_sc+[min_year]) #update minimum year from scotus data
slope, intercept, r_value, p_value, std_err = stats.linregress(x_sc,y_sc) #get basic stats
sc_deg1=np.polyfit(x_sc,y_sc,1); g1 = np.poly1d(sc_deg1) #degree 1 model for SC
p_shift_sc=opt.fsolve(g1-NEUTRAL,2000) #find "paradigm shift" for SC assuming one point of intersection. this is guaranteed for a linear fit.
sc_scatter=ax.scatter(x_sc,y_sc,c='r',marker="+",label='Supreme Court',vmin=-1, vmax=1) #supreme court decisions
ax.plot(x_sc,g1(x_sc),'-r') #plot model for SC data
ax.plot([p_shift_sc], [NEUTRAL], marker='|', markersize=7, color="black") #include vertical lines at crossover moments

ax.axhline(y=NEUTRAL,color='k') #include horizontal neutral opinion line. purple='#551A8B'

ax.legend()
plt.xlabel('Time (year)')
plt.ylabel('Polarity')
plt.title('SCOTUS v. [Public Opinion TBD] on ' + title)
plt.title('SCOTUS v. Public Opinion on ' + title)
plt.grid(True)
plt.yticks(np.arange(-1,2,1),["Conservative","Neutral","Liberal"]) #y-ticks are -1, 0, +1

#fig.colorbar(sc_scatter)

#min_yr=min(x_po+x_sc)
min_yr=min(x_sc+x_po)
plt.axis([min_yr-2, CURRENT_YEAR, -1.1, 1.1])
plt.axis([min_year-2, CURRENT_YEAR, -1.1, 1.1])

#remove previous plot and save new one with title corresponding to keywords
plot_filename = "sc_v_po_" + title + ".png"
Expand Down
39 changes: 15 additions & 24 deletions flask/scvpo.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from search_public_opinions_by_keyword import relevant_questions_anes_df
from polarity_scotus import sc_polarity
from polarity_public import po_polarity
from plot import scotus_plot, public_plot, scotus_v_public_plot
from plot import scotus_v_public_plot

#set up Flask app
app = Flask(__name__)
Expand Down Expand Up @@ -37,38 +37,29 @@ def scotus_v_public():
keywords = [word1,word2,word3]
#search scotus cases via tf-idf of scotus opinion corpus. returns SCDB sub-df.
scotus_results = relevant_cases_scdb_df(keywords,scotus_vocab,scotus_tfidf_matrix_sparse,scotus_opin_id_df,all_scdb_case_data)
scotus_polarity = None
#search public opinions via tf-idf of all public opinion questions. returns ANES codebook sub-df
public_results = relevant_questions_anes_df(keywords,public_vocab,public_tfidf_matrix_sparse,public_opin_id_df,anes_codebook_df)
#no results for either, flash "no output" and don't plot anything
if public_results.empty and scotus_results.empty:
flash("No relevant cases!",'scotus_output')
flash("No relevant questions!",'public_output')
#if only results for public opinion, flash questions and plot public opinion polarity
if (not public_results.empty) and (scotus_results.empty):
flash("No relevant cases!",'scotus_output')
public_polarity = None
#if results for public opinion, flash questions and compute public opinion polarity
if not public_results.empty:
for case_name in public_results['question']:
flash(case_name,'public_output')
rel_vcf_codes = [SURVEY_YEAR_VCF_CODE]+list(public_results['vcf_code']) #get relevant vcf codes including code for survey year
rel_ans_df = anes_response_df.filter(items=rel_vcf_codes) #filter the relevant repsonses/answers by VCF code
plot_filename=public_plot(po_polarity=po_polarity(public_results,rel_ans_df),title="+".join(keywords))
flash(plot_filename,'plot_filename')
public_polarity = po_polarity(public_results,rel_ans_df) #compute polarity of public opinion
else:
flash("No relevant questions!",'public_output')
#if only results for scotus cases, flash cases and plot scotus polarity
if (public_results.empty) and (not scotus_results.empty):
flash("No relevant questions!",'public_output') #no results for PO
if not scotus_results.empty:
for case_name in scotus_results['caseName']:
flash(case_name,'scotus_output')
plot_filename=scotus_plot(sc_polarity=sc_polarity(scotus_results),title="+".join(keywords)) #plot SCOTUS polarity only
flash(plot_filename,'plot_filename')
#if results for both, display both questions and cases and plot polarity
if (not public_results.empty) and (not scotus_results.empty):
for case_name in public_results['question']:
flash(case_name,'public_output')
for case_name in scotus_results['caseName']:
flash(case_name,'scotus_output')
rel_vcf_codes = [SURVEY_YEAR_VCF_CODE]+list(public_results['vcf_code']) #get relevant vcf codes including code for survey year
rel_ans_df = anes_response_df.filter(items=rel_vcf_codes) #filter the relevant repsonses/answers by VCF code
plot_filename=scotus_v_public_plot(sc_polarity=sc_polarity(scotus_results),po_polarity=po_polarity(public_results,rel_ans_df),title="+".join(keywords))
flash(plot_filename,'plot_filename')
scotus_polarity = sc_polarity(scotus_results) #compute polarity of scotus opinions
else:
flash("No relevant cases!",'scotus_output')
#plot with results available. no results ==> empty, neutral plot.
plot_filename=scotus_v_public_plot(sc_polarity=scotus_polarity,po_polarity=public_polarity,title="+".join(keywords))
flash(plot_filename,'plot_filename')
return redirect('/')
return render_template("index.html",title="SCOTUS v. Public Opinion",form=form)

Expand Down

0 comments on commit 6de2010

Please sign in to comment.