I have been using Is it possible to get color gradients under curve in matplotlib? as a reference (you can see the similarities, however i cant for the life of me figure out how to push the shading all the way down to 0 on the Y AXIS, for some reason which i cant find out, it has an upward sloping straight line cutting off the shading, i cant find anything in my data to suggest why its doing this.
for context the y axis can show positive and negative and i want to fill the scale the whole way so using gradient colour to fill from 0 to the line (positive) then fill from 0 to the negative line (see my blue example from a previous chart -same data-)
Here is my code
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
from matplotlib.patches import Polygon
# Variables
AUM = df['#AHD_AUM'].head(104)
MM = df['#AHD_Managed_Money_Net'].head(104)
PRICE = df['#AHD_Price'].head(104)
DATES = df['DATES'].head(104)
# Date Friendly Variables for Plot
List_AUM = df['#AHD_AUM'].head(104).to_list()
List_MM = df['#AHD_Managed_Money_Net'].head(104).to_list()
List_DATES = df['DATES'].head(104).to_list()
X = 0 * df['#AHD_AUM'].head(104)
# Make a date list changing dates with numbers to avoid the issue with the plot
interpreting dates
for i in range(len(df['DATES'].head(104))):
count = i
df['count'][i] = 120 - i
# X and Y data variables changed to arrays as when i had these set as dates
matplotlib hates it
x = df['count'].head(104).to_numpy()
y = df['#AHD_Managed_Money_Net'].head(104).to_numpy()
#DD = AUM.to_numpy()
#MMM = MM.to_numpy()
def main():
for _ in range(len(DD)):
gradient_fill(x,y)
plt.show()
def gradient_fill(x,y, fill_color=None, ax=None, **kwargs):
"""
"""
if ax is None:
ax = plt.gca()
line, = ax.plot(x, y, **kwargs)
if fill_color is None:
fill_color = line.get_color()
zorder = line.get_zorder()
alpha = line.get_alpha()
alpha = 1.0 if alpha is None else alpha
z = np.empty((100, 1, 4), dtype=float)
rgb = mcolors.colorConverter.to_rgb(fill_color)
z[:,:,:3] = rgb
z[:,:,-1] = np.linspace(0, alpha, 100)[:,None]
xmin, xmax, ymin, ymax = x.min(), x.max(), y.min(), y.max()
im = ax.imshow(z, aspect='auto', extent=[xmin, xmax, ymin, ymax],
origin='lower', zorder=zorder)
xy = np.column_stack([x, y])
# xy = np.vstack([[xmin, ymin], xy, [xmax, ymin], [xmin, ymin]]) ### i dont
need this so i have just commented it out
clip_path = Polygon(xy, facecolor='none', edgecolor='none', closed=True)
ax.add_patch(clip_path)
im.set_clip_path(clip_path)
ax.autoscale(True)
return line, im
main()
this is my current output
An easier way to clip the gradient by the curve, is to use a polygon obtained from fill_between.
Here is some example code to get you started.
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(123)
x = np.linspace(0, 10, 200)
y = np.random.normal(0.01, 1, 200).cumsum()
fig, ax = plt.subplots(figsize=(12, 5))
ax.plot(x, y)
ylim = ax.get_ylim()
grad1 = ax.imshow(np.linspace(0, 1, 256).reshape(-1, 1), cmap='Blues', vmin=-0.5, aspect='auto',
extent=[x.min(), x.max(), 0, y.max()], origin='lower')
poly_pos = ax.fill_between(x, y.min(), y, alpha=0.1)
grad1.set_clip_path(poly_pos.get_paths()[0], transform=ax.transData)
poly_pos.remove()
grad2 = ax.imshow(np.linspace(0, 1, 256).reshape(-1, 1), cmap='Reds', vmin=-0.5, aspect='auto',
extent=[x.min(), x.max(), y.min(), 0], origin='upper')
poly_neg = ax.fill_between(x, y, y.max(), alpha=0.1)
grad2.set_clip_path(poly_neg.get_paths()[0], transform=ax.transData)
poly_neg.remove()
ax.set_ylim(ylim)
ax.axhline(0, color='black') # show a line at x=0
plt.show()
PS: vmin in imshow can be used to remove the color range where it's very light:
grad1 = ax.imshow(np.linspace(0, 1, 256).reshape(-1, 1), cmap='Blues', vmin=-0.5, aspect='auto',
extent=[x.min(), x.max(), 0, y.max()], origin='lower')
grad2 = ax.imshow(np.linspace(0, 1, 256).reshape(-1, 1), cmap='Reds', vmin=-0.5, aspect='auto',
extent=[x.min(), x.max(), y.min(), 0], origin='upper')
import pandas as pd # For data handling
import seaborn as sns # For plotting
import numpy as np
import matplotlib.pyplot as plt # For plotting
import matplotlib
#some preferred user settings
plt.rcParams['figure.figsize'] = (18.0, 12.0)
pd.set_option('display.max_columns', None)
%matplotlib inline
import warnings
warnings.filterwarnings(action='ignore')
from mpl_toolkits.axisartist.parasite_axes import HostAxes, ParasiteAxes
import matplotlib.pyplot as plt
from matplotlib.ticker import MultipleLocator
import datetime as dt
import matplotlib.dates as mdates
import pandas
Metal = CAD
# Variables
AUM = Metal.iloc[:,[7]].head(104)
MM = Metal.iloc[:,[0]].head(104)
PRICE = Metal.iloc[:,[8]].head(104)
#Last_Report = Metal.iloc[:,[9]].head(1).dt.strftime('%d %b %Y').to_list()
DATES = Metal.iloc[:,[10]].head(104)
# Dataframe for Net Position High
Net_High = Metal[Metal.iloc[:,[0]] == Metal.iloc[:,[0]].max()]
# Variables for Chart Annotation for Net Position High
Pos_High_Date = Net_High.iloc[:, [0]]
Pos_High_AUM = Net_High.iloc[:, [7]][0]/[1000000000]
Pos_High_Price = Net_High.iloc[:, [8]].to_numpy()[0].round().astype('int')
Pos_High = Net_High.iloc[:, [0]][0].astype('int')
Str_Date = mdates.num2date(Pos_High_Date)
Str_Date = pd.to_datetime(Str_Date[0]).strftime("%d %b %y")[0]
# Dataframe for Net Position Low
Net_Low = df[df['#CAD_Managed_Money_Net'] == df['#CAD_Managed_Money_Net'].head(104).min()]
# Variables for Chart Annotation for Net Position High
Pos_Low_Date = Net_Low.iloc[:, [55]].to_numpy()
Pos_Low_AUM = Net_Low.iloc[:, [26]].to_numpy()[0].round()/[1000000000]
Pos_Low_Price = Net_Low.iloc[:, [27]].to_numpy()[0].round().astype('int')
Pos_Low = Net_Low['#CAD_Managed_Money_Net'][0].astype('int')
Str_Date_Low = mdates.num2date(Pos_Low_Date)
Str_Date_Low = pd.to_datetime(Str_Date_Low[0]).strftime("%d %b %y")[0]
# C Brand Colour Scheme
C = ['deepskyblue', '#003399', 'slategray', '#027608','#cc0000']
def make_patch_spines_invisible(ax):
ax.set_frame_on(True)
ax.patch.set_visible(False)
for sp in ax.spines.values():
sp.set_visible(False)
fig, host = plt.subplots(figsize=(25,15))
fig.subplots_adjust(right=0.8)
#twinx() creates another axes sharing the x axis we do this twice
par1 = host.twinx()
par2 = host.twinx()
# Offset the right spine of par2 the ticks
par2.spines["right"].set_position(("axes",1.08))
#because par2 was created by twinx the frame is off so we need to use the method created above
make_patch_spines_invisible(par2)
# second, show the right spine
par2.spines["right"].set_visible(True)
######### Colouring in Plots
x = DATES
y = MM
ylim = host.get_ylim()
Long = host.imshow(np.linspace(0, 1, 256).reshape(-1, 1), cmap= 'Blues', vmin=-0.5, aspect='auto',
extent=[x.min(), x.max(), 0, y.max()], origin='lower')
poly_pos = host.fill_between(x, y.min(), y, alpha=0.1)
Long.set_clip_path(poly_pos.get_paths()[0], transform=host.transData)
poly_pos.remove()
Short = host.imshow(np.linspace(0, 1, 256).reshape(-1, 1), cmap='OrRd', vmin=-0.5, aspect='auto',
extent=[x.min(), x.max(), y.min(), 0], origin='upper')
poly_neg = host.fill_between(x, y, y.max(), alpha=0.1)
Short.set_clip_path(poly_neg.get_paths()[0], transform=host.transData)
poly_neg.remove()
##########
#plot data
p1, = host.plot(DATES, MM, label="Managed Money Net Position", linewidth=0.0,color = Citi[1], alpha = 0.8)
p2, = par1.plot(DATES, AUM, label="AUM",linewidth=1, marker = '$A$',mew = 1,mfc = 'w', color = Citi[0], alpha = 0.8)
p3, = par2.plot(DATES, PRICE, label="3M Price",linewidth=1, marker = '$p$', color = Citi[2], alpha = 0.8)
#Automatically scale and format
host_labels = ['{:,.0f}'.format(x) + 'K Lots' for x in host.get_yticks()/1000]
host.set_yticklabels(host_labels)
par1_labels = ['{:,.1f}'.format(x) + ' $Billion' for x in par1.get_yticks()/1000000000]
par1.set_yticklabels(par1_labels)
par2_labels = ['{:,.0f}'.format(x) + ' $' for x in par2.get_yticks()]
par2.set_yticklabels(par2_labels)
# x Axis formatting (date)
formatter = matplotlib.dates.DateFormatter('%b- %Y')
host.xaxis.set_major_formatter(formatter)
# Rotates and right-aligns the x labels so they don't crowd each other.
for label in host.get_xticklabels(which='major'):
label.set(rotation=30, horizontalalignment='right')
# Axis Labels
host.set_xlabel("Date")
host.set_ylabel("Managed Money Net Position")
par1.set_ylabel("AUM")
par2.set_ylabel("3M Price")
# Tick Parameters
tkw = dict(size=10, width=2.5)
# Set tick colours
host.tick_params(axis = 'y', colors = Citi[1], **tkw)
par1.tick_params(axis = 'y', colors = Citi[0], **tkw)
par2.tick_params(axis = 'y', colors = Citi[2], **tkw)
#host.tick_params(which='major',axis = 'x',direction='out', colors = Citi[2], **tkw)
#plt.xticks(x, rotation='vertical')
#host.xaxis.set_major_locator(AutoMajorLocator())
host.xaxis.set_major_locator(MultipleLocator(24))
host.tick_params('x',which='major', length=7)
#Label colours taken from plot
host.yaxis.label.set_color(p1.get_color())
par1.yaxis.label.set_color(p2.get_color())
par2.yaxis.label.set_color(p3.get_color())
# Map Title
host.set_title('Aluminium Managed Money Net Positioning as of %s'% Last_Report[0],fontsize='large')
#Colour Spines cant figure out how to do it for the host
par1.spines["right"].set_edgecolor(p2.get_color())
par2.spines["right"].set_edgecolor(p3.get_color())
###### Annotation Tests ##########
## Net Position High Box
host.annotate(f' Net Position High | {Pos_High} \n Date | {Str_Date} \n AUM | ${Pos_High_AUM[0].round(1)} Billion\n 3M Price | ${Pos_High_Price[0]}$',
xy=(Pos_High_Date, Pos_High), xycoords='data',
xytext=(0.02, .85), textcoords='axes fraction',
horizontalalignment='left',
verticalalignment='bottom',
color='white',
bbox=dict(boxstyle="round", fc= Citi[1],edgecolor='white'),
arrowprops=dict(
facecolor='black',
arrowstyle= '->'))
## Net Position Low Box
host.annotate(f' Net Position Low | {Pos_Low} \n Date | {Str_Date_Low} \n AUM | ${Pos_Low_AUM[0].round(1)} Billion\n 3M Price | ${Pos_Low_Price[0]}$',
xy=(Pos_Low_Date, Pos_Low), xycoords='data',
xytext=(0.02, .80), textcoords='axes fraction',
horizontalalignment='left',
verticalalignment='top',
color='white',
bbox=dict(boxstyle="round", fc= Citi[4],edgecolor='white'),
arrowprops=dict(
facecolor='black',
arrowstyle= '->'))
################
# Legend - a little complicated as we have to take from multiple axis
lines = [p1, p2, p3]
########## Plot text and line on chart if you want to
# host.axvline(x = DATES[52] , linestyle='dotted', color='black') ###Dotted Line when Needed
# host.text(2020.3, 10, 'Managed Money \n Aluminium')
# host.text(2020.5, 92, r'Ali',color='black')
# host.text(2020.8,15, r'some event', rotation=90)
host.legend(lines,[l.get_label() for l in lines],loc=2, fontsize=12,frameon=False)
plt.savefig('multiple_axes.png', dpi=300, bbox_inches='tight')
Related
I am creating a 2D matplotlib plot (i and j coordinates) which contains 10 subplots. Each subplot contains 150 by 150 grid cell data. How can I insert a small black-colored square mark (3 by 3 ) somewhere fixed (center at coordinates 62 and 62 ) on each generated heatmap sub-plot across those 10 sub-plots? The square mark would therefore contain 10 blocks from 60 to 64 in both x and y direction and contains a written text "Sale 1" centered at x 62 and y 62. My code below does not generate any patches. Any feedback is greatly appreciated.
from matplotlib.patches import Rectangle
import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import r2_score, median_absolute_error
import os
import matplotlib.cm as cm
from mpl_toolkits import axes_grid1
import matplotlib.pyplot as plt
#import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import matplotlib.colors
import matplotlib.colors as colors
data = np.random.rand(10, 150, 150)
data = data.reshape(-1, 1)
property = "Sale"
pmin = data.min()
pmax = data.max()
v = np.linspace(round(pmin,3), round(pmax,3),15, endpoint=True)
v = [round(x,3) for x in v]
fig, ax = plt.subplots(2, 5, figsize=(160, 80))
row_count = 0
col_count = 0
for i in range(10):
sub_plot_data = data[(i)*(150*150):(i+1)*150*150]
x = 150
y = 150
#--------------------------- Define the map boundary ----------------------
xmin = 1258096.6
xmax = 1291155.0
ymin = 11251941.6
ymax = 11285000.0
pmin = min(sub_plot_data)
pmax = max(sub_plot_data)
# --------------------------- define color bar for Discrete color
bounds = np.linspace(-1, 1, 10)
Discrete_colors = plt.get_cmap('jet')(np.linspace(0,1,len(bounds)+1))
# create colormap without the outmost colors
cmap = mcolors.ListedColormap(Discrete_colors[1:-1]) #
actual_2d = np.reshape(sub_plot_data,(y,x))
im1 = ax[row_count, col_count].imshow(actual_2d, interpolation=None, cmap=cmap,
extent=(xmin, xmax, ymin, ymax), vmin=pmin, vmax=pmax)
plt.text(actual_2d[62, 62], actual_2d[62, 62], '%s' % 'Sale_1',
horizontalalignment='center', verticalalignment='center', color= 'black', fontsize= 90)
ax[row_count, col_count].set_title("Sale_Stores-%s - L: %s"%(i+1, layer),
fontsize=130, pad=44, x=0.5, y=0.999) # new
ax[row_count, col_count].set_aspect('auto')
ax[row_count, col_count].tick_params(left=False, labelleft=False, top=False,
labeltop=False, right=False, labelright=False, bottom=False, labelbottom=False) # new
#ax[row_count, col_count] = plt.gca()
plt.gca().add_patch(Rectangle((60, 60), 3, 3, edgecolor='black',
facecolor='black',fill=True,lw=2))
ax[row_count, col_count].add_patch(plt.text(62, 62, '%s' % 'Sale_1',
horizontalalignment='center', verticalalignment='center', color= 'black', fontsize= 90))
col_count +=1
if col_count == 5:
row_count +=1
col_count =0
fig.tight_layout(h_pad=10)
plt.subplots_adjust(left=0.02,
bottom=0.1,
right=0.91,
top=0.8,
wspace=0.1,
hspace=0.2)
cbaxes = fig.add_axes([0.94, 0.05, 0.02, 0.8])
cbar = fig.colorbar(im1, ax=ax.ravel().tolist(), ticks=v, extend='both', cax =cbaxes)
cbar.ax.tick_params(labelsize=70)
#cbar.set_ticks(v)
cbar.ax.set_yticklabels([i for i in v], fontsize=120)
output_dir = r"D/test"
plot_dir = os.path.join(output_dir, reservoir_property)
if not os.path.exists(plot_dir):
os.makedirs(plot_dir)
fig.savefig(r"%s/per_allmodel.png"%(plot_dir))
I tried your code and made a couple of modifications: first, the graph size was too huge and caused errors, so I made it smaller; second, I simplified the subplots: axes has a list of subplot objects, so I took them out with axes.flat; third The second is modifying the text as annotations. The graph size has been reduced and the font size and spacing have been adjusted, so please modify it yourself. Finally, tick_params is not set since the color bar ticks are disabled.
fig, axes = plt.subplots(2, 5, figsize=(16, 8))
row_count = 0
col_count = 0
for i,ax in enumerate(axes.flat):
sub_plot_data = data[(i)*(150*150):(i+1)*150*150]
x = 150
y = 150
#--------------------------- Define the map boundary ----------------------
xmin = 1258096.6
xmax = 1291155.0
ymin = 11251941.6
ymax = 11285000.0
pmin = min(sub_plot_data)
pmax = max(sub_plot_data)
# --------------------------- define color bar for Discrete color
bounds = np.linspace(-1, 1, 10)
Discrete_colors = plt.get_cmap('jet')(np.linspace(0,1,len(bounds)+1))
# create colormap without the outmost colors
cmap = mcolors.ListedColormap(Discrete_colors[1:-1]) #
actual_2d = np.reshape(sub_plot_data,(y,x))
#im = ax.imshow(actual_2d, interpolation=None, cmap=cmap, extent=(xmin, xmax, ymin, ymax), vmin=pmin, vmax=pmax)
im = ax.imshow(actual_2d, interpolation=None, cmap=cmap)
ax.text(actual_2d[62, 62], actual_2d[62, 62]-10, '%s' % 'Sale_1',
horizontalalignment='center', verticalalignment='center', color= 'black', fontsize=18)
ax.set_title("Sale_Stores-%s - L: %s"%(i+1, 1), fontsize=14, pad=30, x=0.5, y=0.999)
ax.set_aspect('auto')
ax.add_patch(Rectangle((60, 60), 6, 6, edgecolor='red', facecolor='red', fill=True, lw=2))
ax.text(62, 62, '%s' % 'Sale_1', ha='center', va='center', color='black', fontsize=14)
fig.tight_layout(h_pad=10)
plt.subplots_adjust(left=0.02,
bottom=0.1,
right=0.91,
top=0.8,
wspace=0.1,
hspace=0.5)
cbaxes = fig.add_axes([0.94, 0.05, 0.02, 0.8])
cbar = fig.colorbar(im, ax=axes.flat, ticks=v, extend='both', cax=cbaxes)
cbar.ax.tick_params(labelsize=10)
#cbar.set_ticks(v)
cbar.ax.set_yticklabels([str(i) for i in v], fontsize=12)
#plt.tick_params(left=False, labelleft=False, top=False, labeltop=False, right=False, labelright=False, bottom=False, labelbottom=False)
plt.show()
I am working on an assignment that I have pretty much already completed, but I wanted to add a small touch to it that attempts to fill the area between the two lines with a colormap based on temperature instead of just a simple color. The way the lines are plotted makes them separate entities essentially, so I know that I'll likely need two colormaps that meet each other or overlap to accomplish this but I'm not too sure how to accomplish this. Any assistance is greatly appreciated.
from datetime import datetime
import pandas as pd
import numpy as np
import matplotlib.colors as mcol
import matplotlib.cm as cm
bin = 400
hash = 'fb441e62df2d58994928907a91895ec62c2c42e6cd075c2700843b89'
Temp = pd.read_csv('fb441e62df2d58994928907a91895ec62c2c42e6cd075c2700843b89.csv'.format(bin, hash))
Temp['Date'] = pd.to_datetime(Temp['Date'])
#Only doing this here because the mplleaflet in my personal jupyter notebook is bugged
#will take longer to execute, will take more lines of code for conversions and ultimately is less efficient than simply doing it with pandas.
#print(datetime.strptime(Temp['Date'].to_json(), '%y-%m-%d')) = datetime.strptime(Temp['Date'], format)
Temp['Y'] = Temp['Date'].dt.year
Temp['M'] = Temp['Date'].dt.month
Temp['D'] = Temp['Date'].dt.day
Temp['DV'] = Temp['Data_Value'].div(10)
Temp['E'] = Temp['Element']
Temp = Temp[~((Temp['M']==2) & (Temp['D']==29))]
GrMin = Temp[(Temp['E']=='TMIN') & (Temp['Y']>=2005) & (Temp['Y']<2015)].groupby(['M','D']).agg({'DV':np.min})
FinMin = Temp[(Temp['E']=='TMIN') & (Temp['Y']==2015)].groupby(['M','D']).agg({'DV':np.min})
GrMax = Temp[(Temp['E']=='TMAX') & (Temp['Y']>=2005) & (Temp['Y']<2015)].groupby(['M','D']).agg({'DV':np.max})
FinMax = Temp[(Temp['E']=='TMIN') & (Temp['Y']==2015)].groupby(['M','D']).agg({'DV':np.max})
#x = GrMax
#y = GrMin
#X, Y = np.meshgrid(x,y)
#Z = f(X, Y)
AnomMin = FinMin[FinMin['DV'] < GrMin['DV']]
AnomMax = FinMax[FinMax['DV'] > GrMax['DV']]
#temps = range(-30,40)
plt.figure(figsize=(18, 10), dpi = 80)
red = '#FF0000'
blue = '#0800FF'
cm1 = mcol.LinearSegmentedColormap.from_list('Temperature Map',[blue, red])
cnorm = mcol.Normalize(vmin=min(GrMin['DV']),vmax=max(GrMax['DV']))
cpick = cm.ScalarMappable(norm=cnorm,cmap=cm1)
cpick.set_array([])
plt.title('Historical Temperature Analysis In Ann Arbor Michigan')
plt.xlabel('Month')
plt.ylabel('Temperature in Celsius')
plt.plot(GrMax.values, c = red, linestyle = '-', label = 'Highest Temperatures (2005-2014)')
#plt.scatter(AnomMax, FinMax.iloc[AnomMax], c = red, s=5, label = 'Anomolous High Readings (2015)')
plt.plot(GrMin.values, c = blue, linestyle = '-', label = 'Lowest Temperatures (2005-2014)')
#plt.scatter(AnomMin, FinMin.iloc[AnomMin], c = blue, s=5, label = 'Anomolous Low Readings (2015)')
plt.xticks(np.linspace(0,60 + 60*11, num=12),(r'January',r'February',r'March',r'April',r'May',r'June',r'July',r'August',r'September',r'October',r'November',r'December'))
#Failed Attempt
#plt.contourf(X, Y, Z, 20, cmap = cm1)
#for i in temps
# plt.fill_between(len(GrMin['DV']), GrMin['DV'], i ,cmap = cm1)
#for i in temps
# plt.fill_between(len(GrMin['DV']), i ,GrMax['DV'], cmap = cm1)
#Kind of Close but doesn't exactly create the colormap
plt.gca().fill_between(range(len(GrMin.values)), GrMin['DV'], GrMax['DV'], cmap = cm1)
plt.legend(loc = '0', title='Temperature Guide')
plt.colorbar(cpick, label='Temperature in Celsius')
plt.show()
Current result:
You could draw a colored rectangle covering the curves. And use the polygon created by fill_between to clip that rectangle:
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap
import numpy as np
x = np.linspace(0, 10, 200)
y1 = np.random.normal(0.02, 1, 200).cumsum() + 20
y2 = np.random.normal(0.05, 1, 200).cumsum() + 50
cm1 = LinearSegmentedColormap.from_list('Temperature Map', ['blue', 'red'])
polygon = plt.fill_between(x, y1, y2, lw=0, color='none')
xlim = (x.min(), x.max())
ylim = plt.ylim()
verts = np.vstack([p.vertices for p in polygon.get_paths()])
gradient = plt.imshow(np.linspace(0, 1, 256).reshape(-1, 1), cmap=cm1, aspect='auto', origin='lower',
extent=[verts[:, 0].min(), verts[:, 0].max(), verts[:, 1].min(), verts[:, 1].max()])
gradient.set_clip_path(polygon.get_paths()[0], transform=plt.gca().transData)
plt.xlim(xlim)
plt.ylim(ylim)
plt.show()
A more complicated alternative, would color such that the upper curve corresponds to red and the lower curve to blue:
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 200)
y1 = np.random.normal(0.02, 1, 200).cumsum() + 20
y2 = np.random.normal(0.05, 1, 200).cumsum() + 50
polygon = plt.fill_between(x, y1, y2, lw=0, color='none')
ylim = plt.ylim()
verts = np.vstack([p.vertices for p in polygon.get_paths()])
ymin, ymax = verts[:, 1].min(), verts[:, 1].max()
gradient = plt.imshow(np.array([np.interp(np.linspace(ymin, ymax, 200), [y1i, y2i], np.arange(2))
for y1i, y2i in zip(y1, y2)]).T,
cmap='turbo', aspect='auto', origin='lower', extent=[x.min(), x.max(), ymin, ymax])
gradient.set_clip_path(polygon.get_paths()[0], transform=plt.gca().transData)
plt.ylim(ylim)
plt.show()
A variant could be to smooth out the color values in the horizontal direction (but still clip using the original curves):
from scipy.ndimage import gaussian_filter
gradient = plt.imshow(np.array([np.interp(np.linspace(ymin, ymax, 200), [y1i, y2i], np.arange(2))
for y1i, y2i in zip(gaussian_filter(y1, 4, mode='nearest'),
gaussian_filter(y2, 4, mode='nearest'))]).T,
cmap='turbo', aspect='auto', origin='lower', extent=[x.min(), x.max(), ymin, ymax])
After correcting some functional errors within my code then applying the code provided by JohanC as well as asking for some other much-needed guidance, I was able to successfully complete the colormap. It would probably be more visually appealing if the upper and lower line plots were a different color but as far as the colormap is concerned, mission accomplished. Thanks again for the assistance!
from datetime import datetime
import pandas as pd
import numpy as np
import matplotlib.colors as mcol
import matplotlib.cm as cm
bin = 400
hash = 'fb441e62df2d58994928907a91895ec62c2c42e6cd075c2700843b89'
Temp = pd.read_csv('fb441e62df2d58994928907a91895ec62c2c42e6cd075c2700843b89.csv'.format(bin, hash))
Temp['Date'] = pd.to_datetime(Temp['Date'])
#Only doing this here because the mplleaflet in my personal jupyter notebook is bugged
#will take longer to execute, will take more lines of code for conversions and ultimately is less efficient than simply doing it with pandas.
#print(datetime.strptime(Temp['Date'].to_json(), '%y-%m-%d')) = datetime.strptime(Temp['Date'], format)
Temp['Y'] = Temp['Date'].dt.year
Temp['M'] = Temp['Date'].dt.month
Temp['D'] = Temp['Date'].dt.day
Temp['DV'] = Temp['Data_Value'].div(10)
Temp['E'] = Temp['Element']
Temp = Temp[~((Temp['M']==2) & (Temp['D']==29))]
GrMin = Temp[(Temp['E']=='TMIN') & (Temp['Y']>=2005) & (Temp['Y']<2015)].groupby(['M','D']).agg({'DV':np.min})
FinMin = Temp[(Temp['E']=='TMIN') & (Temp['Y']==2015)].groupby(['M','D']).agg({'DV':np.min})
GrMax = Temp[(Temp['E']=='TMAX') & (Temp['Y']>=2005) & (Temp['Y']<2015)].groupby(['M','D']).agg({'DV':np.max})
FinMax = Temp[(Temp['E']=='TMAX') & (Temp['Y']==2015)].groupby(['M','D']).agg({'DV':np.max})
GrMax = GrMax.reset_index()
GrMin = GrMin.reset_index()
FinMax = FinMax.reset_index()
FinMin = FinMin.reset_index()
#x = GrMax
#y = GrMin
#X, Y = np.meshgrid(x,y)
#Z = f(X, Y)
AnomMin = FinMin[FinMin['DV'] < GrMin['DV']]
AnomMax = FinMax[FinMax['DV'] > GrMax['DV']]
#temps = range(-30,40)
plt.figure(figsize=(18, 10), dpi = 160)
red = '#FF0000'
blue = '#0800FF'
cm1 = mcol.LinearSegmentedColormap.from_list('Temperature Map',[blue, red])
cnorm = mcol.Normalize(vmin=min(GrMin['DV']),vmax=max(GrMax['DV']))
cpick = cm.ScalarMappable(norm=cnorm,cmap=cm1)
cpick.set_array([])
plt.title('Historical Temperature Analysis In Ann Arbor Michigan')
plt.xlabel('Month')
plt.ylabel('Temperature in Celsius')
plt.plot(GrMax['DV'], c = red, linestyle = '-', label = 'Highest Temperatures (2005-2014)')
plt.scatter(AnomMax.index, AnomMax['DV'], c = red, s=2, label = 'Anomolous High Readings (2015)')
plt.plot(GrMin['DV'], c = blue, linestyle = '-', label = 'Lowest Temperatures (2005-2014)')
plt.scatter(AnomMin.index, AnomMin['DV'], c = blue, s=2, label = 'Anomolous Low Readings (2015)')
plt.xticks(np.linspace(0,365,12, endpoint = True),(r'January',r'February',r'March',r'April',r'May',r'June',r'July',r'August',r'September',r'October',r'November',r'December'))
#Start: Assisted from StackOverFlow user JohanC v
x = np.arange(len(GrMin['DV'].fillna(0).astype('float64').ravel()))
y1 = GrMax['DV'].fillna(0).astype('float64').ravel()
y2 = GrMin['DV'].fillna(0).astype('float64').ravel()
polygon = plt.fill_between(x, y1, y2, lw=0, color='none')
xlim = (x.min(), x.max())
ylim = plt.ylim()
verts = np.vstack([p.vertices for p in polygon.get_paths()])
gradient = plt.imshow(np.linspace(1, 0, 256).reshape(-1, 1), cmap=cm1, aspect='auto',
extent=[verts[:, 0].min(), verts[:, 0].max(), verts[:, 1].min(), verts[:, 1].max()])
gradient.set_clip_path(polygon.get_paths()[0], transform=plt.gca().transData)
plt.xlim(xlim)
plt.ylim(ylim)
#Finish: Assisted from StackOverFlow user JohanC ^
#Failed Attempt at gradient fill with colormap
#plt.contourf(X, Y, Z, 20, cmap = cm1)
#for i in temps
# plt.fill_between(len(GrMin['DV']), GrMin['DV'], i ,cmap = cm1)
#for i in temps
# plt.fill_between(len(GrMin['DV']), i ,GrMax['DV'], cmap = cm1)
#Kind of Close but doesn't exactly create the colormap
#plt.gca().fill_between(range(len(GrMin.values)), GrMin['DV'], GrMax['DV'], facecolor = 'grey', alpha = 0.10)
plt.legend(loc = 'lower center', title='Temperature Guide')
plt.colorbar(cpick, label='Temperature in Celsius')
plt.show()
enter image description here
I am working on an assignment that I have pretty much already completed, but I wanted to add a small touch to it that attempts to fill the area between the two lines with a colormap based on temperature instead of just a simple color. The way the lines are plotted makes them separate entities essentially, so I know that I'll likely need two colormaps that meet each other or overlap to accomplish this but I'm not too sure how to accomplish this. Any assistance is greatly appreciated.
from datetime import datetime
import pandas as pd
import numpy as np
import matplotlib.colors as mcol
import matplotlib.cm as cm
bin = 400
hash = 'fb441e62df2d58994928907a91895ec62c2c42e6cd075c2700843b89'
Temp = pd.read_csv('fb441e62df2d58994928907a91895ec62c2c42e6cd075c2700843b89.csv'.format(bin, hash))
Temp['Date'] = pd.to_datetime(Temp['Date'])
#Only doing this here because the mplleaflet in my personal jupyter notebook is bugged
#will take longer to execute, will take more lines of code for conversions and ultimately is less efficient than simply doing it with pandas.
#print(datetime.strptime(Temp['Date'].to_json(), '%y-%m-%d')) = datetime.strptime(Temp['Date'], format)
Temp['Y'] = Temp['Date'].dt.year
Temp['M'] = Temp['Date'].dt.month
Temp['D'] = Temp['Date'].dt.day
Temp['DV'] = Temp['Data_Value'].div(10)
Temp['E'] = Temp['Element']
Temp = Temp[~((Temp['M']==2) & (Temp['D']==29))]
GrMin = Temp[(Temp['E']=='TMIN') & (Temp['Y']>=2005) & (Temp['Y']<2015)].groupby(['M','D']).agg({'DV':np.min})
FinMin = Temp[(Temp['E']=='TMIN') & (Temp['Y']==2015)].groupby(['M','D']).agg({'DV':np.min})
GrMax = Temp[(Temp['E']=='TMAX') & (Temp['Y']>=2005) & (Temp['Y']<2015)].groupby(['M','D']).agg({'DV':np.max})
FinMax = Temp[(Temp['E']=='TMIN') & (Temp['Y']==2015)].groupby(['M','D']).agg({'DV':np.max})
#x = GrMax
#y = GrMin
#X, Y = np.meshgrid(x,y)
#Z = f(X, Y)
AnomMin = FinMin[FinMin['DV'] < GrMin['DV']]
AnomMax = FinMax[FinMax['DV'] > GrMax['DV']]
#temps = range(-30,40)
plt.figure(figsize=(18, 10), dpi = 80)
red = '#FF0000'
blue = '#0800FF'
cm1 = mcol.LinearSegmentedColormap.from_list('Temperature Map',[blue, red])
cnorm = mcol.Normalize(vmin=min(GrMin['DV']),vmax=max(GrMax['DV']))
cpick = cm.ScalarMappable(norm=cnorm,cmap=cm1)
cpick.set_array([])
plt.title('Historical Temperature Analysis In Ann Arbor Michigan')
plt.xlabel('Month')
plt.ylabel('Temperature in Celsius')
plt.plot(GrMax.values, c = red, linestyle = '-', label = 'Highest Temperatures (2005-2014)')
#plt.scatter(AnomMax, FinMax.iloc[AnomMax], c = red, s=5, label = 'Anomolous High Readings (2015)')
plt.plot(GrMin.values, c = blue, linestyle = '-', label = 'Lowest Temperatures (2005-2014)')
#plt.scatter(AnomMin, FinMin.iloc[AnomMin], c = blue, s=5, label = 'Anomolous Low Readings (2015)')
plt.xticks(np.linspace(0,60 + 60*11, num=12),(r'January',r'February',r'March',r'April',r'May',r'June',r'July',r'August',r'September',r'October',r'November',r'December'))
#Failed Attempt
#plt.contourf(X, Y, Z, 20, cmap = cm1)
#for i in temps
# plt.fill_between(len(GrMin['DV']), GrMin['DV'], i ,cmap = cm1)
#for i in temps
# plt.fill_between(len(GrMin['DV']), i ,GrMax['DV'], cmap = cm1)
#Kind of Close but doesn't exactly create the colormap
plt.gca().fill_between(range(len(GrMin.values)), GrMin['DV'], GrMax['DV'], cmap = cm1)
plt.legend(loc = '0', title='Temperature Guide')
plt.colorbar(cpick, label='Temperature in Celsius')
plt.show()
Current result:
You could draw a colored rectangle covering the curves. And use the polygon created by fill_between to clip that rectangle:
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap
import numpy as np
x = np.linspace(0, 10, 200)
y1 = np.random.normal(0.02, 1, 200).cumsum() + 20
y2 = np.random.normal(0.05, 1, 200).cumsum() + 50
cm1 = LinearSegmentedColormap.from_list('Temperature Map', ['blue', 'red'])
polygon = plt.fill_between(x, y1, y2, lw=0, color='none')
xlim = (x.min(), x.max())
ylim = plt.ylim()
verts = np.vstack([p.vertices for p in polygon.get_paths()])
gradient = plt.imshow(np.linspace(0, 1, 256).reshape(-1, 1), cmap=cm1, aspect='auto', origin='lower',
extent=[verts[:, 0].min(), verts[:, 0].max(), verts[:, 1].min(), verts[:, 1].max()])
gradient.set_clip_path(polygon.get_paths()[0], transform=plt.gca().transData)
plt.xlim(xlim)
plt.ylim(ylim)
plt.show()
A more complicated alternative, would color such that the upper curve corresponds to red and the lower curve to blue:
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 200)
y1 = np.random.normal(0.02, 1, 200).cumsum() + 20
y2 = np.random.normal(0.05, 1, 200).cumsum() + 50
polygon = plt.fill_between(x, y1, y2, lw=0, color='none')
ylim = plt.ylim()
verts = np.vstack([p.vertices for p in polygon.get_paths()])
ymin, ymax = verts[:, 1].min(), verts[:, 1].max()
gradient = plt.imshow(np.array([np.interp(np.linspace(ymin, ymax, 200), [y1i, y2i], np.arange(2))
for y1i, y2i in zip(y1, y2)]).T,
cmap='turbo', aspect='auto', origin='lower', extent=[x.min(), x.max(), ymin, ymax])
gradient.set_clip_path(polygon.get_paths()[0], transform=plt.gca().transData)
plt.ylim(ylim)
plt.show()
A variant could be to smooth out the color values in the horizontal direction (but still clip using the original curves):
from scipy.ndimage import gaussian_filter
gradient = plt.imshow(np.array([np.interp(np.linspace(ymin, ymax, 200), [y1i, y2i], np.arange(2))
for y1i, y2i in zip(gaussian_filter(y1, 4, mode='nearest'),
gaussian_filter(y2, 4, mode='nearest'))]).T,
cmap='turbo', aspect='auto', origin='lower', extent=[x.min(), x.max(), ymin, ymax])
After correcting some functional errors within my code then applying the code provided by JohanC as well as asking for some other much-needed guidance, I was able to successfully complete the colormap. It would probably be more visually appealing if the upper and lower line plots were a different color but as far as the colormap is concerned, mission accomplished. Thanks again for the assistance!
from datetime import datetime
import pandas as pd
import numpy as np
import matplotlib.colors as mcol
import matplotlib.cm as cm
bin = 400
hash = 'fb441e62df2d58994928907a91895ec62c2c42e6cd075c2700843b89'
Temp = pd.read_csv('fb441e62df2d58994928907a91895ec62c2c42e6cd075c2700843b89.csv'.format(bin, hash))
Temp['Date'] = pd.to_datetime(Temp['Date'])
#Only doing this here because the mplleaflet in my personal jupyter notebook is bugged
#will take longer to execute, will take more lines of code for conversions and ultimately is less efficient than simply doing it with pandas.
#print(datetime.strptime(Temp['Date'].to_json(), '%y-%m-%d')) = datetime.strptime(Temp['Date'], format)
Temp['Y'] = Temp['Date'].dt.year
Temp['M'] = Temp['Date'].dt.month
Temp['D'] = Temp['Date'].dt.day
Temp['DV'] = Temp['Data_Value'].div(10)
Temp['E'] = Temp['Element']
Temp = Temp[~((Temp['M']==2) & (Temp['D']==29))]
GrMin = Temp[(Temp['E']=='TMIN') & (Temp['Y']>=2005) & (Temp['Y']<2015)].groupby(['M','D']).agg({'DV':np.min})
FinMin = Temp[(Temp['E']=='TMIN') & (Temp['Y']==2015)].groupby(['M','D']).agg({'DV':np.min})
GrMax = Temp[(Temp['E']=='TMAX') & (Temp['Y']>=2005) & (Temp['Y']<2015)].groupby(['M','D']).agg({'DV':np.max})
FinMax = Temp[(Temp['E']=='TMAX') & (Temp['Y']==2015)].groupby(['M','D']).agg({'DV':np.max})
GrMax = GrMax.reset_index()
GrMin = GrMin.reset_index()
FinMax = FinMax.reset_index()
FinMin = FinMin.reset_index()
#x = GrMax
#y = GrMin
#X, Y = np.meshgrid(x,y)
#Z = f(X, Y)
AnomMin = FinMin[FinMin['DV'] < GrMin['DV']]
AnomMax = FinMax[FinMax['DV'] > GrMax['DV']]
#temps = range(-30,40)
plt.figure(figsize=(18, 10), dpi = 160)
red = '#FF0000'
blue = '#0800FF'
cm1 = mcol.LinearSegmentedColormap.from_list('Temperature Map',[blue, red])
cnorm = mcol.Normalize(vmin=min(GrMin['DV']),vmax=max(GrMax['DV']))
cpick = cm.ScalarMappable(norm=cnorm,cmap=cm1)
cpick.set_array([])
plt.title('Historical Temperature Analysis In Ann Arbor Michigan')
plt.xlabel('Month')
plt.ylabel('Temperature in Celsius')
plt.plot(GrMax['DV'], c = red, linestyle = '-', label = 'Highest Temperatures (2005-2014)')
plt.scatter(AnomMax.index, AnomMax['DV'], c = red, s=2, label = 'Anomolous High Readings (2015)')
plt.plot(GrMin['DV'], c = blue, linestyle = '-', label = 'Lowest Temperatures (2005-2014)')
plt.scatter(AnomMin.index, AnomMin['DV'], c = blue, s=2, label = 'Anomolous Low Readings (2015)')
plt.xticks(np.linspace(0,365,12, endpoint = True),(r'January',r'February',r'March',r'April',r'May',r'June',r'July',r'August',r'September',r'October',r'November',r'December'))
#Start: Assisted from StackOverFlow user JohanC v
x = np.arange(len(GrMin['DV'].fillna(0).astype('float64').ravel()))
y1 = GrMax['DV'].fillna(0).astype('float64').ravel()
y2 = GrMin['DV'].fillna(0).astype('float64').ravel()
polygon = plt.fill_between(x, y1, y2, lw=0, color='none')
xlim = (x.min(), x.max())
ylim = plt.ylim()
verts = np.vstack([p.vertices for p in polygon.get_paths()])
gradient = plt.imshow(np.linspace(1, 0, 256).reshape(-1, 1), cmap=cm1, aspect='auto',
extent=[verts[:, 0].min(), verts[:, 0].max(), verts[:, 1].min(), verts[:, 1].max()])
gradient.set_clip_path(polygon.get_paths()[0], transform=plt.gca().transData)
plt.xlim(xlim)
plt.ylim(ylim)
#Finish: Assisted from StackOverFlow user JohanC ^
#Failed Attempt at gradient fill with colormap
#plt.contourf(X, Y, Z, 20, cmap = cm1)
#for i in temps
# plt.fill_between(len(GrMin['DV']), GrMin['DV'], i ,cmap = cm1)
#for i in temps
# plt.fill_between(len(GrMin['DV']), i ,GrMax['DV'], cmap = cm1)
#Kind of Close but doesn't exactly create the colormap
#plt.gca().fill_between(range(len(GrMin.values)), GrMin['DV'], GrMax['DV'], facecolor = 'grey', alpha = 0.10)
plt.legend(loc = 'lower center', title='Temperature Guide')
plt.colorbar(cpick, label='Temperature in Celsius')
plt.show()
enter image description here
Can someone help me make the R2 writing look like the rest? Especially not italics. This is my code below:
While I'm here can anyone tell me how to either
get that R2=0.97 line in red writing to indicate that's what the red line is on the graph
or
insert a red line/red dash within the legend on that line?
I've seen other ways of doing it online but the way I've formatted my legend doesn't allow for it.
plt.rcParams["font.family"] = "Cambria"
fig, ax = plt.subplots()
ax.scatter(y_test, y_predicted ,s=10,color='darkslateblue',linewidths=1)
ax.plot([y.min(), y.max()], [y.min(), y.max()], 'k-', lw=2,)
ax.set_xlabel('Actual (%)',fontsize='large')
ax.set_ylabel('Predicted (%)',fontsize='large')
y_test, y_predicted = y_test.reshape(-1,1), y_predicted.reshape(-1,1)
ax.plot(y_test, LinearRegression().fit(y_test, y_predicted).predict(y_test), color="red", lw=2)
ax.set_title('H2O REF')
handles = [mpl_patches.Rectangle((0, 0), 1, 1, fc="white", ec="white",
lw=0, alpha=0)] * 4
labels = []
labels.append("$R^2$ = {0:.2g}".format(Rsquared))
labels.append("RMSE = {0:.2g}".format(rmse))
labels.append("MAE = {0:.2g}".format(mae))
ax.legend(handles, labels, loc='best', fontsize='x-large',
fancybox=True, framealpha=0.7,
handlelength=0, handletextpad=0)
plt.show()
Thank you :)
For the first solution, a possible way to achieve it is by only typesetting ^2 in the math environment and than setting the first label text to red as described here, see code below.
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.patches as mpl_patches
x = np.linspace(0, 1)
y = x + np.random.normal(scale=0.1, size=50)
plt.rcParams["font.family"] = "Cambria"
Rsquared = 0.9
rmse = 0.8
mae = 1
fig, ax = plt.subplots()
ax.scatter(x, y)
ax.plot(x, x, c='r')
handles = [mpl_patches.Rectangle((0, 0), 1, 1, fc="white", ec="white",
lw=0, alpha=0)] * 4
labels = []
labels.append("R$^2$ = {0:.2g}".format(Rsquared))
labels.append("RMSE = {0:.2g}".format(rmse))
labels.append("MAE = {0:.2g}".format(mae))
leg = ax.legend(handles, labels, loc='best', fontsize='x-large',
fancybox=True, framealpha=0.7,
handlelength=0, handletextpad=0)
texts = leg.get_texts()
texts[0].set_color("red")
Alternatively, you can create legend entries including the red line with Line2D.
The corresponding code down below overrides handles[0].
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.patches as mpl_patches
from matplotlib.lines import Line2D
x = np.linspace(0, 1)
y = x + np.random.normal(scale=0.1, size=50)
plt.rcParams["font.family"] = "Cambria"
Rsquared = 0.9
rmse = 0.8
mae = 1
fig, ax = plt.subplots()
ax.scatter(x, y)
ax.plot(x, x, c='r')
handles = [mpl_patches.Rectangle((0, 0), 1, 1, fc="white", ec="white",
lw=0, alpha=0)] * 4
lines = []
handles[0] = Line2D([0], [0], color='red')
labels = []
labels.append("R$^2$ = {0:.2g}".format(Rsquared))
labels.append("RMSE = {0:.2g}".format(rmse))
labels.append("MAE = {0:.2g}".format(mae))
leg = ax.legend(handles, labels, loc='best', fontsize='x-large',
fancybox=True, framealpha=0.7)
Here I tried to add the polar plot on top of the Cartesian grid,but what I got instead was 2 separate figures(one polar another Cartesian),I want this polar figure to be embedded in the Cartesian plot. Also I have used some of the code previously available as I am new to matplotlib.
from pylab import *
import matplotlib.pyplot as plt
x = [0,10,-3,-10]
y = [0,10,1,-10]
color=['w','w','w','w']
fig = plt.figure()
ax1 = fig.add_subplot(111)
scatter(x,y, s=100 ,marker='.', c=color,edgecolor='w')
circle1=plt.Circle((0,0),5,color='r',fill=False)
circle_min=plt.Circle((0,0),4.5,color='g',fill=False)
circle_max=plt.Circle((0,0),5.445,color='b',fill=False)
fig = plt.gcf()
fig.gca().add_artist(circle1)
fig.gca().add_artist(circle_min)
fig.gca().add_artist(circle_max)
left,right = ax1.get_xlim()
low,high = ax1.get_ylim()
arrow( left, 0, right -left, 0, length_includes_head = True, head_width = 0.15 )
arrow( 0, low, 0, high-low, length_includes_head = True, head_width = 0.15 )
grid()
fig = plt.figure()
ax2 = fig.add_subplot(111)
scatter(x,y, s=100 ,marker='.', c=color,edgecolor='w')
circle2=plt.Circle((0,0),5,color='r',fill=False)
circle_min=plt.Circle((0,0),4.5,color='g',fill=False)
circle_max=plt.Circle((0,0),5.445,color='b',fill=False)
fig = plt.gcf()
fig.gca().add_artist(circle2)
fig.gca().add_artist(circle_min)
fig.gca().add_artist(circle_max)
left,right = ax2.get_xlim()
low,high = ax2.get_ylim()
arrow( left, 0, right -left, 0, length_includes_head = True, head_width = 0.15 )
arrow( 0, low, 0, high-low, length_includes_head = True, head_width = 0.15 )
import numpy as np
import matplotlib.pyplot as plt
theta = np.linspace(-np.pi, np.pi, 100)
r1 = 1 - np.sin(3*theta)
r2 = 1 + np.cos(theta)
ax = plt.subplot(111, polar=True, # add subplot in polar coordinates
axisbg='Azure') # background colour
ax.set_rmax(2.2) # r maximum value
ax.grid(True) # add the grid
ax.plot(theta, r1,
color='Tomato', # line colour
ls='--', # line style
lw=3, # line width
label='a 3-fold curve') # label
ax.plot(theta, r2,
color='purple',
linewidth=3,
ls = '-',
label = 'a cardioid')
ax.legend(loc="lower right") # legend location
titlefont = {
'family' : 'serif',
'color' : 'black',
'weight' : 'bold',
'size' : 16,
}
ax.set_title("A plot in polar coordinates", # title
va='bottom', # some space below the title
fontdict = titlefont # set the font properties
)
grid()
show()
#I am getting a separate Cartesian image + a polar image while what I need is both the things in a single image
import matplotlib.pyplot as plt
import numpy as np
#########################################
color=['w','w','w','w']
theta = np.linspace(-np.pi, np.pi, 100)
fig = plt.figure()# initializing the figure
rect = [0.1, 0.1, 0.8, 0.8]# setting the axis limits in [left, bottom, width, height]
ax_carthesian = fig.add_axes(rect)# the carthesian axis:
ax_polar = fig.add_axes(rect, polar=True, frameon=False)# the polar axis:
#########################################
ax_carthesian.add_artist(plt.Circle((0.5,0.5),5/15,color='r',fill=False))
ax_carthesian.add_artist(plt.Circle((0.5,0.5),4.5/15,color='g',fill=False))
ax_carthesian.add_artist(plt.Circle((0.5,0.5),5.445/15,color='b',fill=False))
ax_polar.plot(theta, 1 - np.sin(3*theta), color='Tomato',ls='--',lw=1, label='a 3-fold curve')
ax_polar.plot(theta, 1 + np.cos(theta), color='purple',linewidth=1,ls = '-',label = 'a cardioid')
plt.show()
I am not used to matplotlib but I reduced your code to his minimum to better understand it and make it look less redudant. look at what I get:
import pylab
import matplotlib.pyplot as plt
import numpy as np
#########################################
x = [0,10,-3,-10]
y = [0,10,1,-10]
color=['w','w','w','w']
theta = np.linspace(-np.pi, np.pi, 100)
#########################################
pylab.scatter(x,y, s=100 ,marker='.', c=color,edgecolor='w')
plt.gcf().gca().add_artist(plt.Circle((0,0),5,color='r',fill=False))
plt.gcf().gca().add_artist(plt.Circle((0,0),4.5,color='g',fill=False))
plt.gcf().gca().add_artist(plt.Circle((0,0),5.445,color='b',fill=False))
plt.figure().add_subplot(111)
ax = plt.subplot(111, polar=True,axisbg='Azure')
ax.plot(theta, 1 - np.sin(3*theta),color='Tomato',ls='--',lw=3,label='a 3-fold curve')
ax.plot(theta, 1 + np.cos(theta),color='purple',linewidth=3,ls = '-',label = 'a cardioid')
pylab.show()
it is nearly the same result...