<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Plotting and Fitting with Python
Step1:  Simple Plotting
Step2:  Simple plotting - with style
The default style of matplotlib is a bit lacking in style. Some would term it ugly. The new version of matplotlib has added some new styles that you can use in place of the default. Changing the style will effect all of the rest of the plots on the notebook.
Step3:  In addition, you can specify colors in many different ways
Step4:  Simple Histograms
Step5:  You have better control of the plot with the object oriented interface.
While most plt functions translate directly to ax methods (such as plt.plot() → ax.plot(), plt.legend() → ax.legend(), etc.), this is not the case for all commands.
In particular, functions to set limits, labels, and titles are slightly modified.
For transitioning between matlab-style functions and object-oriented methods, make the following changes
Step6:  Subplots
subplot(rows,columns)
Access each subplot like a matrix. [x,y]
For example
Step7:  An Astronomical Example - Color Magnitude Diagrams
Step8:  Curve Fitting
Step9:  Fitting a specific function
Step10:  $$ \Large f(x) = a \sin(bx) $$
Step11:  Bad initial guesses can lead to very bad fits
Step12:  Plotting Extras
Adding Legends
Step13:  Polar Plots
Step14:  Everyone likes Pie
Step15:  Pseudo 3D plots
<ASSISTANT_TASK:>
Python Code:
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
from astropy.table import QTable
Explanation: Plotting and Fitting with Python
End of explanation
t = np.linspace(0,2,100)               # 100 points linearly spaced between 0.0 and 2.0
s = np.cos(2*np.pi*t) * np.exp(-t)     # s if a function of t
plt.plot(t,s)
Explanation: Simple Plotting
End of explanation
plt.style.available
plt.style.use('ggplot')
plt.plot(t,s)
plt.xlabel('time (s)')
plt.ylabel('voltage (mV)')
plt.title('This is a title')
plt.ylim(-1.5,1.5)
plt.plot(t, s, color='b', marker='None', linestyle='--');   # adding the ';' at then suppresses the Out[] line
mask1 = np.where((s>-0.4) & (s<0))
plt.plot(t, s, color='b', marker='None', linestyle='--')
plt.plot(t[mask1],s[mask1],color="g",marker="o",linestyle="None",markersize=8);
Explanation: Simple plotting - with style
The default style of matplotlib is a bit lacking in style. Some would term it ugly. The new version of matplotlib has added some new styles that you can use in place of the default. Changing the style will effect all of the rest of the plots on the notebook.
End of explanation
from astropy import units as u
from astropy.visualization import quantity_support
quantity_support()
v = 10 * u.m / u.s
t2 = np.linspace(0,10,1000) * u.s
y = v * t2
plt.plot(t2,y)
Explanation: In addition, you can specify colors in many different ways:
Grayscale intensities: color = '0.8'
RGB triplets: color = (0.3, 0.1, 0.9)
Hex strings: color = '#7ff00'
HTML color names: color = 'Chartreuse'
matplotlib will work with Astropy units
End of explanation
#Histogram of "h" with 20 bins
np.random.seed(42)
h = np.random.randn(500)
plt.hist(h, bins=20, facecolor='MediumOrchid');
mask2 = np.where(h>0.0)
np.random.seed(42)
j = np.random.normal(2.0,1.0,300)  # normal dist, ave = 2.0, std = 1.0
plt.hist(h[mask2], bins=20, facecolor='#b20010', histtype='stepfilled')
plt.hist(j,        bins=20, facecolor='#0200b0', histtype='stepfilled', alpha = 0.30);
Explanation: Simple Histograms
End of explanation
fig,ax = plt.subplots(1,1)                    # One window
fig.set_size_inches(11,8.5)                   # (width,height) - letter paper landscape
fig.tight_layout()                          # Make better use of space on plot
ax.set_xlim(0.0,1.5)
ax.spines['bottom'].set_position('zero')    # Move the bottom axis line to x = 0
ax.set_xlabel("This is X")
ax.set_ylabel("This is Y")
ax.plot(t, s, color='b', marker='None', linestyle='--')
ax.text(0.8, 0.6, 'Bad Wolf', color='green', fontsize=36)            # You can place text on the plot
ax.vlines(0.4, -0.4, 0.8, color='m', linewidth=3)                    # vlines(x, ymin, ymax)
ax.hlines(0.8,  0.2, 0.6, color='y', linewidth=5)                    # hlines(y, xmin, xmax)
fig.savefig('fig1.png', bbox_inches='tight')
!ls *.png
!display fig1.png
Explanation: You have better control of the plot with the object oriented interface.
While most plt functions translate directly to ax methods (such as plt.plot() → ax.plot(), plt.legend() → ax.legend(), etc.), this is not the case for all commands.
In particular, functions to set limits, labels, and titles are slightly modified.
For transitioning between matlab-style functions and object-oriented methods, make the following changes:
plt.xlabel()  → ax.set_xlabel()
plt.ylabel() → ax.set_ylabel()
plt.xlim()  → ax.set_xlim()
plt.ylim() → ax.set_ylim()
plt.title() → ax.set_title()
End of explanation
fig, ax = plt.subplots(2,2)                                               # 2 rows 2 columns
fig.set_size_inches(11,8.5)                                               # width, height
fig.tight_layout()                                                        # Make better use of space on plot
ax[0,0].plot(t, s, color='b', marker='None', linestyle='--')              # Plot at [0,0]
ax[0,1].hist(h, bins=20, facecolor='MediumOrchid')                        # Plot at [0,1]
ax[1,0].hist(j,bins=20, facecolor='HotPink', histtype='stepfilled')       # Plot at [1,0]
ax[1,1].set_xscale('log')                                                 # Plot at [1,1] - x-axis set to log
ax[1,1].plot(t, s, color='r', marker='None', linestyle='--'); 
Explanation: Subplots
subplot(rows,columns)
Access each subplot like a matrix. [x,y]
For example: subplot(2,2) makes four panels with the coordinates:
End of explanation
T = QTable.read('M15_Bright.csv', format='ascii.csv')
T[0:3]
fig, ax = plt.subplots(1,2)                 # 1 row, 2 colums
fig.set_size_inches(15,5)
fig.tight_layout()
# The plot for [0,0]
ax[0].set_xlim(-40,140)
ax[0].set_ylim(-120,120)
ax[0].set_aspect('equal')                    # Force intervals in x = intervals in y
ax[0].invert_xaxis()                         # RA increases to the left!
ax[0].set_xlabel("$\Delta$RA [sec]")
ax[0].set_ylabel("$\Delta$Dec [sec]")
ax[0].plot(T['RA'], T['Dec'],color="g",marker="o",linestyle="None",markersize=5);
# The plot for [0,1]
BV = T['Bmag'] - T['Vmag']
V = T['Vmag']
ax[1].set_xlim(-0.25,1.5)
ax[1].set_ylim(12,19)
ax[1].set_aspect(1/6)         # Make 1 unit in X = 6 units in Y
ax[1].invert_yaxis()          # Magnitudes increase to smaller values
ax[1].set_xlabel("B-V")
ax[1].set_ylabel("V")
ax[1].plot(BV,V,color="b",marker="o",linestyle="None",markersize=5);
# overplotting
maskC = np.where((V < 16.25) & (BV < 0.55))     
ax[0].plot(T['RA'][maskC], T['Dec'][maskC],color="r",marker="o",linestyle="None",markersize=4, alpha=0.5)
ax[1].plot(BV[maskC], V[maskC],color="r",marker="o",linestyle="None",markersize=4, alpha=0.5);
Explanation: An Astronomical Example - Color Magnitude Diagrams
End of explanation
D1 = QTable.read('data1.csv', format='ascii.csv')
D1[0:2]
plt.plot(D1['x'],D1['y'],marker="o",linestyle="None",markersize=5);
# 1-D fit y = ax + b
Fit1 = np.polyfit(D1['x'],D1['y'],1)
Fit1       # The coefficients of the fit (a,b)
Yfit = np.polyval(Fit1,D1['x'])   # The polynomial of Fit1 applied to the points D1['x']
plt.plot(D1['x'], D1['y'], marker="o", linestyle="None", markersize=5)
plt.plot(D1['x'], Yfit, linewidth=4, color='c', linestyle='--')
D2 = QTable.read('data2.csv', format='ascii.csv')
plt.plot(D2['x'],D2['y'],marker="o",linestyle="None",markersize=5);
# 2-D fit y = ax**2 + bx + c
Fit2 = np.polyfit(D2['x'],D2['y'],2)
Fit2
Yfit = np.polyval(Fit2,D2['x'])
plt.plot(D2['x'], D2['y'], marker="o", linestyle="None", markersize=5)
plt.plot(D2['x'], Yfit, linewidth=3, color='y', linestyle='--');
# Be careful, very high-order fits may be garbage
Fit3 = np.polyfit(D1['x'],D1['y'],20)
xx = np.linspace(0,10,200)
Yfit = np.polyval(Fit3,xx)
plt.plot(D1['x'], D1['y'], marker="o", linestyle="None", markersize=8)
plt.plot(xx, Yfit, linewidth=3, color='m', linestyle='--');
plt.ylim(-20,120)
Explanation: Curve Fitting
End of explanation
D3 = QTable.read('data3.csv', format='ascii.csv')
plt.plot(D3['x'],D3['y'],marker="o",linestyle="None",markersize=5);
from scipy.optimize import curve_fit
Explanation: Fitting a specific function
End of explanation
def ringo(x,a,b):
    return a*np.sin(b*x)
Aguess = 75
Bguess = 1.0/5.0
fitpars, error = curve_fit(ringo,D3['x'],D3['y'],p0=[Aguess,Bguess])
# Function to fit = ringo
# X points to fit = D3['x']
# Y points to fit = D3['y']
# Initial guess at values for a,b = [Aguess,Bguess]
print(fitpars)
Z = np.linspace(0,100,1000)
plt.plot(Z, ringo(Z, *fitpars), 'r-')
plt.plot(Z, ringo(Z,Aguess,Bguess), 'g--')
plt.plot(D3['x'],D3['y'],marker="o",linestyle="None",markersize=5);
Explanation: $$ \Large f(x) = a \sin(bx) $$
End of explanation
Aguess = 35
Bguess = 1.0
fitpars, error = curve_fit(ringo,D3['x'],D3['y'],p0=[Aguess,Bguess])
print(fitpars)
plt.plot(Z, ringo(Z, *fitpars), 'r-')
plt.plot(Z, ringo(Z,Aguess,Bguess), 'g--')
plt.plot(D3['x'],D3['y'],marker="o",linestyle="None",markersize=5);
Explanation: Bad initial guesses can lead to very bad fits
End of explanation
theta = np.linspace(0.0,2*np.pi,300)
y1 = abs(np.sin(theta))
y2 = -abs(np.cos(theta))
plt.plot(theta, y1, color="b", label="|Sin|")
plt.plot(theta, y2, color="r", label="-|Cos|")
plt.legend(loc=0,shadow=True);
Explanation: Plotting Extras
Adding Legends
End of explanation
plt.polar(theta,theta/5.0,label="spiral")
plt.polar(theta,np.cos(4*theta),label="flower")
plt.legend(loc=2, frameon=False);
Explanation: Polar Plots
End of explanation
plt.axis('equal')
labels = ('John', 'Paul' ,'George' ,'Ringo')     # Name of slices
sizes = [0.3, 0.15, 0.45, 0.10]                  # Size of slices
colors = ['r', 'g', 'b', 'c']                    # Color of Slices
explode = (0, 0, 0.1, 0)                         # Offset slide 3
plt.pie(sizes,explode=explode,labels=labels,colors=colors,shadow=True);
Explanation: Everyone likes Pie
End of explanation
from mpl_toolkits.mplot3d import Axes3D
ax = plt.axes(projection='3d')
xx = np.cos(3*theta)
yy = np.sin(2*theta)
ax.plot(theta,xx,yy);
ax.view_init(azim = -140,elev = 15)
Explanation: Pseudo 3D plots
End of explanation
<END_TASK>