I'm using subplot2grid and trying make fill_between() work for the second subplot.
It does work, but for some reason it shows orange dots. How can I get rid of those dots?
Notice the orange dots in the second subplot
In the last 3 lines of code is where the fill_between() appears, but posting all the relevant code for the chart (the data is in pandas dataframes)
length = len(df.index)
fig6 = plt.figure(figsize=(14,11))
ax1_f6 = plt.subplot2grid((9,1),(0,0), rowspan=5, colspan=1)
titulo = "{0} ".format(assets[0])
fig6.suptitle(titulo, fontsize=15, color='#0079a3')
# V.1) data for first subplot
x6 = mdates.date2num(df.index[-length:].to_pydatetime())
y6 = df.PX_LAST[-length:].values
z6 = df.trend_noise_thr_mean[-length:].values
cmap = ListedColormap(['r','y','g'])
norm = BoundaryNorm([-1.5,-1,0,1,1.5], cmap.N)
points = np.array([x6,y6]).T.reshape(-1, 1, 2)
segments= np.concatenate([points[:-1], points[1:]], axis=1)
lc = LineCollection(segments, cmap=cmap, norm=norm)
lc.set_array(z6)
lc.set_linewidth(3)
ax1_f6=plt.gca()
ax1_f6.add_collection(lc)
ax1_f6.set_xlim(x6.min(), x6.max())
ax1_f6.set_ylim(y6.min(), y6.max())
ax1_f6.xaxis.set_major_formatter(mdates.DateFormatter('%d/%m/%Y'))
ax1_f6.plot(df.emaw.index[-length:], df.emaw[-length:], '-', lw=0.7, label='EMA', color='r')
# V.2) data of the second subplot
ax2_f6 = plt.subplot2grid((9,1),(6,0), rowspan=4, colspan=1, sharex=ax1_f6)
axb2_f6 = ax2_f6.twinx()
test = (df.noise - df.mean)
axb2_f6.plot_date(test.index[-length:], test[-length:], lw=1, label='test')
axb2_f6.fill_between(test.index, test, 0, where=(test >= 0), facecolor='g', alpha=0.3, interpolate=True)
axb2_f6.fill_between(test.index, test, 0, where=(test < 0), facecolor='r', alpha=0.3, interpolate=True)
plot_date uses marker='o' by default. Pass marker=None to the method to get rid of the dots:
axb2_f6.plot_date(test.index[-length:], marker=None, test[-length:], lw=1, label='test')
Related
I'm ploting a map and having a problem with matplotlib colorbar. The last but one color is missing, it must representate the number 200. And the 200 and the 250 are with the same color. What I have to do?
def maps(values, lonsi, latsi, title, title_archive, nws_precip_colors = [
'#FFFFFF',
"#e2f4fc",
"#81d2fa",
'#1777ba',
'#032677',
'#78be21',
'#3ca611',
"#008e00",
"#2c460c",
"#f2c31b",
"#ff7700",
"#de3400",
"#aa0000",
"#600000",
"#cd7ef5", # the missing color
"#9611d6",
],
levels = [0,1,5,10,15,20,25,30,40,50,70,90,120,150,200,250], val=16):
fpath = 'font/Montserrat-Regular.ttf'
prop = fm.FontProperties(fname=fpath)
fig, ax = plt.subplots(subplot_kw={'projection': ccrs.PlateCarree()})
fig.set_size_inches(15, 10, forward=True)
ax.set_extent([-75.5,-30,-31,6.5])
grid=ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=True,linewidth=0.05, color='gray', alpha=0.5)
precip_colormap = colors.ListedColormap(nws_precip_colors)
norm = colors.BoundaryNorm(levels, val)
data_crs = ccrs.PlateCarree()
cs = ax.contourf(lonsi, latsi, values, transform=data_crs, levels=levels, cmap=precip_colormap, add_colorbar=False, extend='both', alpha=0.8, norm=norm)
reader_p = shpr.Reader('Countries_Shape/ne_10m_admin_0_countries.shp')
shape_country=ShapelyFeature(reader_p.geometries(),ccrs.PlateCarree(), linewidth=1 , facecolor=(1,1,1,0), edgecolor='grey')
ax.add_feature(shape_country)
plt.title(title, fontsize=20, pad=30, fontweight='bold', color='grey', fontproperties=prop)
cbar=plt.colorbar(cs)
cbar.set_ticks(levels)
cbytick_obj = plt.getp(cbar.ax.axes, 'yticklabels')
plt.setp(cbytick_obj, color='grey')
fig.show()
fig.savefig(f'{title_archive}.png',
bbox_inches ="tight",
pad_inches = 0.5,
facecolor ="#ffffff",
orientation ='landscape',
dpi=100)
the result:
result
I tried put val = 17, but it didn't worked. Don't know what to do!
I'm creating a chart with matplotlib, here is my code:
fig = plt.figure(facecolor='#131722',dpi=155, figsize=(8, 4))
ax1 = plt.subplot2grid((1,2), (0,0), facecolor='#131722')
Colors = [['#0400ff', '#FF0000'], ['#09ff00', '#ff8c00']]
for x in List:
Index = List.index(x)
rate_buy = []
total_buy = []
for y in x['data']['bids']:
rate_buy.append(y[0])
total_buy.append(y[1])
rBuys = pd.DataFrame({'buy': rate_buy})
tBuys = pd.DataFrame({'total': total_buy})
ax1.plot(rBuys.buy, tBuys.total, color=Colors[Index][0], linewidth=0.5, alpha=0.8)
ax1.fill_between(rBuys.buy, 0, tBuys.total, facecolor=Colors[Index][0], alpha=1)
And here is the output:
The problem with the current output is that the colors of the two areas are "merging": basically the area BELOW the blue line should be blue, but instead it's green. How can i set it to be blue, for example, like in my example?
Example List data:
[[9665, 0.07062500000000001], [9666, 0.943708], [9667, 5.683787000000001], [9668, 9.802289], [9669, 11.763305], [9670, 14.286004], [9671, 16.180122], [9672, 23.316723000000003], [9673, 30.915156000000003], [9674, 33.44226200000001], [9675, 36.14526200000001], [9676, 45.76024100000001], [9677, 51.85294700000001], [9678, 58.79529300000001], [9679, 59.05322900000001], [9680, 60.27704500000001], [9681, 60.743885000000006], [9682, 66.75103700000001], [9683, 71.86412600000001], [9684, 73.659636], [9685, 78.08502800000001], [9686, 78.19614200000001], [9687, 79.98396400000001], [9688, 90.55855800000002]]
I guess the hint of #JohanC is correct, you are plotting in the wrong order and overlay your previous plots with new ones.
I tried to recreate a small example where total_buy1 > total_buy0, so in order to get the desired result you first have to plot total_buy1
and then total_buy0:
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
Colors = [['#0400ff', '#FF0000'],
['#09ff00', '#ff8c00']]
n = 100
rate_buy = np.linspace(0, 1000, 100)
total_buy0 = np.linspace(0, 300, n)[::-1] + np.random.normal(scale=10, size=n)
total_buy1 = np.linspace(0, 600, n)[::-1] + np.random.normal(scale=10, size=n)
ax.plot(rate_buy, total_buy1, color=Colors[1][1], linewidth=0.5, alpha=0.8)
ax.fill_between(rate_buy, 0, total_buy1, facecolor=Colors[1][0], alpha=1)
ax.plot(rate_buy, total_buy0, color=Colors[0][1], linewidth=0.5, alpha=0.8)
ax.fill_between(rate_buy, 0, total_buy0, facecolor=Colors[0][0], alpha=1)
I noticed that you use Colors[Index][0] for both plotting calls, so the line and the area will not have different colors.
I am using the following script to generate some plots. The problem is sometimes the scientific notation is overlapping with the title.
Is there a way to fix this like moving the plot a little bit down?
# init
u = {}
o = {}
# create figure
fig = plt.figure()
# x-Axis (timesteps)
i = np.array(i)
for key in urbs_values.keys():
# y-Axis (values)
u[key] = np.array(urbs_values[key])
o[key] = np.array(oemof_values[key])
# draw plots
plt.plot(i, u[key], label='urbs_'+str(key), linestyle='None', marker='x')
plt.ticklabel_format(axis='y', style='sci', scilimits=(0, 0))
plt.plot(i, o[key], label='oemof_'+str(key), linestyle='None', marker='.')
plt.ticklabel_format(axis='y', style='sci', scilimits=(0, 0))
# plot specs
plt.xlabel('Timesteps [h]')
plt.ylabel('Flow [MWh]')
plt.title(site+' '+name)
plt.grid(True)
plt.tight_layout(rect=[0,0,0.7,1])
plt.legend(bbox_to_anchor=(1.025, 1), loc=2, borderaxespad=0)
# plt.show()
Example:
You can change the position of the title by providing a value for the y parameter in plt.title(...), e.g., plt.title(site+' '+name, y=1.1).
You can edit the tittle position this way:
# plot specs
plt.xlabel('Timesteps [h]')
plt.ylabel('Flow [MWh]')
plt.title(site+' '+name)
ttl = plt.title
ttl.set_position([.5, 1.02])
plt.grid(True)
plt.tight_layout(rect=[0,0,0.7,1])
plt.legend(bbox_to_anchor=(1.025, 1), loc=2, borderaxespad=0)
# plt.show()
tuning the '1.02' should do the trick
I do same thing that answered here
def get_angle_plot(line1, line2, offset = 1, color = None, origin = [0,0], len_x_axis = 1, len_y_axis = 1):
l1xy = line1.get_xydata()
slope1 = (l1xy[1][1] - l1xy[0][1]) / float(l1xy[1][0] - l1xy[0][0])
angle1 = abs(math.degrees(math.atan(slope1))) # Taking only the positive angle
l2xy = line2.get_xydata()
slope2 = (l2xy[1][1] - l2xy[0][1]) / float(l2xy[1][0] - l2xy[0][0])
angle2 = abs(math.degrees(math.atan(slope2)))
theta1 = min(angle1, angle2)
theta2 = max(angle1, angle2)
angle = theta2 - theta1
if color is None:
color = line1.get_color() # Uses the color of line 1 if color parameter is not passed.
return Arc(origin, len_x_axis*offset, len_y_axis*offset, 0, theta1, theta2, color=color, label = str(angle)+u"\u00b0")
And when Line2D-s same as in example. All work just fine.
fig = plt.figure()
line_1 = Line2D([0,1], [0,4], linewidth=1, linestyle = "-", color="green")
line_2 = Line2D([0,4.5], [0,3], linewidth=1, linestyle = "-", color="red")
ax = fig.add_subplot(1,1,1)
ax.add_line(line_1)
ax.add_line(line_2)
angle_plot = get_angle_plot(line_1, line_2, 1)
ax.add_patch(angle_plot) # To display the angle arc
plt.show()
But when i change slightly to this
line_1 = Line2D([10,30], [1,2], linewidth=1, linestyle = "-", color="green")
line_2 = Line2D([10,30], [1,1], linewidth=1, linestyle = "-", color="red")
I get white empty plot 1*1 size. Not 2*30 if be more refined
You need to set the origin to the point where the two lines intersect. In this case origin = [10,1].
Then you may want to relimit the axes, because the lines you want to show are outside the range [0,1]. You may use ax.relim(); ax.autoscale_view() for that purpose.
line_1 = Line2D([10,30], [1,2], linewidth=1, linestyle = "-", color="green")
line_2 = Line2D([10,30], [1,1], linewidth=1, linestyle = "-", color="red")
ax = fig.add_subplot(1,1,1)
ax.add_line(line_1)
ax.add_line(line_2)
angle_plot = get_angle_plot(line_1, line_2, 1, origin = [10,1])
ax.add_patch(angle_plot) # To display the angle arc
ax.relim()
ax.autoscale_view()
plt.show()
Note that the easier option is surely to not define the lines as Line2D but simply as usual plot. That makes it unnecessary to relimit the axes.
ax = fig.add_subplot(1,1,1)
line_1, = ax.plot([10,30], [1,2], linewidth=1, linestyle = "-", color="green")
line_2, = ax.plot([10,30], [1,1], linewidth=1, linestyle = "-", color="red")
angle_plot = get_angle_plot(line_1, line_2, 5, origin = [10,1])
ax.add_patch(angle_plot) # To display the angle arc
plt.show()
Because the x and y scales are so differently the result will look more like a straight line.
After moving all of my 'y' axes to subplots I get an unwanted axis. It's the black one on the left. Does anyone know how to get rid of it? I'm sure it's getting plotted when I call the figure, however I'm not sure how to get rid of it.
def mpl_plot(self, plot_page, replot = 0): #Data stored in lists
if plot_page == 1: #Plot 1st Page
#plt0 = self.mplwidget.axes
fig = self.mplwidget.figure #Add a figure
if plot_page == 2: #Plot 2nd Page
#plt0 = self.mplwidget_2.axes
fig = self.mplwidget_2.figure #Add a figure
if plot_page == 3: #Plot 3rd Page
#plt0 = self.mplwidget_3.axes
fig = self.mplwidget_3.figure #Add a figure
#Clears Figure if data is roplotted
if replot == 1:
fig.clf()
par0 = fig.add_subplot(111)
par1 = fig.add_subplot(111)
par2 = fig.add_subplot(111)
#Add Axes
plt = par0.twinx()
ax1 = par1.twinx()
ax2 = par2.twinx()
impeller = str(self.comboBox_impellers.currentText()) #Get Impeller
fac_curves = self.mpl_factory_specs(impeller)
fac_lift = fac_curves[0]
fac_power = fac_curves[1]
fac_flow = fac_curves[2]
fac_eff = fac_curves[3]
fac_max_eff = fac_curves[4]
fac_max_eff_bpd = fac_curves[5]
fac_ranges = self.mpl_factory_ranges()
min_range = fac_ranges[0]
max_range = fac_ranges[1]
#Plot Chart
plt.hold(True)
plt.plot(fac_flow, fac_lift, 'b', linestyle = "dashed", linewidth = 1)
ax1.plot(fac_flow, fac_power, 'r', linestyle = "dashed", linewidth = 1)
ax2.plot(fac_flow, fac_eff, 'g', linestyle = "dashed", linewidth = 1)
#Move spines
ax2.spines["right"].set_position(("outward", 25))
self.make_patch_spines_invisible(ax2)
ax2.spines["right"].set_visible(True)
#Plot x axis minor tick marks
minorLocatorx = AutoMinorLocator()
ax1.xaxis.set_minor_locator(minorLocatorx)
ax1.tick_params(which='both', width= 0.5)
ax1.tick_params(which='major', length=7)
ax1.tick_params(which='minor', length=4, color='k')
#Plot y axis minor tick marks
minorLocatory = AutoMinorLocator()
plt.yaxis.set_minor_locator(minorLocatory)
plt.tick_params(which='both', width= 0.5)
plt.tick_params(which='major', length=7)
plt.tick_params(which='minor', length=4, color='k')
#Make Border of Chart White
fig.set_facecolor('white')
#Plot Grid
plt.grid(b=True, which='both', color='k', linestyle='-')
#set shaded Area
plt.axvspan(min_range, max_range, facecolor='#9BE2FA', alpha=0.5) #Yellow rectangular shaded area
#Set Vertical Lines
plt.axvline(fac_max_eff_bpd, color = '#69767A')
#BEP MARKER *** Can change marker style if needed
bep = fac_max_eff * 0.90 #bep is 90% of maximum efficiency point
bep_corrected = bep * 0.90 # We knock off another 10% to place the arrow correctly on chart
ax2.annotate('BEP', xy=(fac_max_eff_bpd, bep_corrected), xycoords='data', #Subtract 2.5 shows up correctly on chart
xytext=(-50, 30), textcoords='offset points',
bbox=dict(boxstyle="round", fc="0.8"),
arrowprops=dict(arrowstyle="-|>",
shrinkA=0, shrinkB=10,
connectionstyle="angle,angleA=0,angleB=90,rad=10"),
)
#Set Scales
plt.set_ylim(0,max(fac_lift) + (max(fac_lift) * 0.40)) #Pressure
#plt.set_xlim(0,max(fac_flow))
ax1.set_ylim(0,max(fac_power) + (max(fac_power) * 0.40)) #Power
ax2.set_ylim(0,max(fac_eff) + (max(fac_eff) * 0.40)) #Effiency
plt.yaxis.tick_left()
# Set Axes Colors
plt.tick_params(axis='y', colors='b')
ax1.tick_params(axis='y', colors='r')
ax2.tick_params(axis='y', colors='g')
# Set Chart Labels
plt.yaxis.set_label_position("left")
plt.set_xlabel("BPD")
plt.set_ylabel("Feet" , color = 'b')
#ax1.set_ylabel("BHP", color = 'r')
#ax1.set_ylabel("Effiency", color = 'g')
# Set tight layout
fig.set_tight_layout
# Since we moved Feet Axis to subplot, extra unneeded axis was created. This Removes it
# Refresh
fig.canvas.update()
fig.canvas.draw()
Well it looks like you have three y-axes, referencing the one you want to not be shown, you could try adding:
ax.yaxis.set_tick_params(labelsize=0, length=0, which='major')
to just make invisible the labels and ticks. I think it's ax2 you want gone?