Multi axes timeseries line graph using matplotlib - pandas

I am trying to create multi axis line chart where the x-axis are dates using matplotlib. As you can see in the picture below, the lines are close but all seem to be finishing on the left axis which is not correct.
Here is my code:
df.Date = pd.to_datetime(df.Date)
fig, ax = plt.subplots()
ax2= ax.twinx()
ax2.set_frame_on(True)
ax2.patch.set_visible(False)
fig.subplots_adjust(right=0.75)
years = YearLocator() # every year
months = MonthLocator() # every month
yearsFmt = DateFormatter('%Y')
ax.plot_date(df.Date,df.A, fmt="r-")
ax.plot_date(df.Date,df.B, fmt="b-")
ax2.plot_date(df.Date,df.C, fmt="y-")
ax2.plot_date(df.Date,df.D, fmt="g-")
ax.xaxis.set_major_locator(years)
ax.xaxis.set_major_formatter(yearsFmt)
ax.xaxis.set_minor_locator(months)
ax.autoscale_view()
ax2.xaxis.set_major_locator(years)
ax2.xaxis.set_major_formatter(yearsFmt)
ax2.xaxis.set_minor_locator(months)
ax2.autoscale_view()
plt.setp(ax.get_xticklabels(), fontsize=10, rotation='vertical')
plt.setp(ax2.get_xticklabels(), fontsize=10, rotation='vertical')
ax.fmt_xdata = DateFormatter('%b\n%Y')
ax2.fmt_xdata = DateFormatter('%b\n%Y')
fig.autofmt_xdate()
plt.setp(ax.get_xticklabels(), fontsize=10, rotation='vertical')
ax.set_ylabel('(%)')
ax2.set_ylabel('(%)')
ax2.set_xlabel('Date')
plt.title('Chart 1. ', fontsize=8, weight= 'bold')
plt.tight_layout()
plt.show()

need to use df1= df.sort_values(by='Date'). When i took a closer look at the data, there were a few dates out of order towards the end of the dataset that were causing the plot to revert back to 2002, causing the line to move towards the left of the graph.

Related

Integration of a piecewise regression in a subplot

I have the following code of a piecewise_regression:
data = data_heatmap_2017.copy()
data = data[['tre200h0_2017','Leistung:']].dropna()
xx = data['tre200h0_2017'].values.tolist()
yy = data['Leistung:'].values.tolist()
pw_fit = piecewise_regression.Fit(xx, yy, n_breakpoints=1)
pw_fit.summary()
If I do a single plot with the code below, I get a diagram piecewise_regression:
# Plot the data, fit, breakpoints and confidence intervals
pw_fit.plot_data(s=0.1)
# Pass in standard matplotlib keywords to control any of the plots
pw_fit.plot_fit(color="red", linewidth=2)
pw_fit.plot_breakpoints()
pw_fit.plot_breakpoint_confidence_intervals()
plt.xlabel("Lufttemperatur [°C]")
plt.ylabel("Leistung [kW]")
plt.show()
plt.close()
Now I would like to integrate the diagram piecewise regression within this subplots on position ax10:
fig, axs = plt.subplots(2, 5, figsize=(60,50), dpi=(100))
ax10 = axs[1,0]
ax10.set_title('2017, Signatur, Zähler: ' + Zaehler)
ax10.pw_fit.plot_data(s=0.1)
ax10.pw_fit.plot_fit(color="red", linewidth=2)
ax10.set_xlabel('Lufttemperatur [°C]')
ax10.set_ylabel('Leistung [kW]')
ax10.axis([-15, 35, min_Power, max_Power])
plt.show()
plt.close()
unfortunately the lines
ax10.pw_fit.plot_data(s=0.1)
ax10.pw_fit.plot_fit(color="red", linewidth=2)
do not work with the prefix ax10. I get an AttributeError 'AxesSubplot' object has no attribute 'pw_fit'. Any idea how to solve this? Thank you!

y and x axis subplots matplotlib

A quite basic question about ticks' labels for x and y-axis. According to this code
fig, axes = plt.subplots(6,12, figsize=(50, 24), constrained_layout=True, sharex=True , sharey=True)
fig.subplots_adjust(hspace = .5, wspace=.5)
custom_xlim = (-1, 1)
custom_ylim = (-0.2,0.2)
for i in range(72):
x_data = ctheta[i]
y_data = phi[i]
y_err = err_phi[i]
ax = fig.add_subplot(6, 12, i+1)
ax.plot(x_data_new, bspl(x_data_new))
ax.axis('off')
ax.errorbar(x_data,y_data, yerr=y_err, fmt="o")
ax.set_xlim(custom_xlim)
ax.set_ylim(custom_ylim)
I get the following output:
With y labels for plots on the first column and x labels for theone along the last line, although I call them off.
Any idea?
As #BigBen wrote in their comment, your issue is caused by you adding axes to your figure twice, once via fig, axes = plt.subplots() and then once again within your loop via fig.add_subplot(). As a result, the first set of axes is still visible even after you applied .axis('off') to the second set.
Instead of the latter, you could change your loop to:
for i in range(6):
for j in range(12):
ax = axes[i,j] # these are the axes created via plt.subplots(6,12,...)
ax.axis('off')
# … your other code here

Matplotlib Plot Every Other Month w/Ticks and Grid lines Each Month

I have code that looks like this below and I'm trying to plot every other month on the x axis starting with "Jan" with xticks/grid lines vertical at every or each month and year shown. However, i've tried two solutions and nothing happens and i get no error. In other words, it seems like the options I've tried don't have any effect on the plot. Here is the code for the plot portion and you can see I've tried "MonthLocator" and "mdates".
#PRODUCE AND VISUALIZE FORECAST
pred_uc = results.get_forecast(steps=6)
pred_ci = pred_uc.conf_int()
import matplotlib.dates as mdates
#from matplotlib.dates import MonthLocator
ax = y['2019':].plot(label='observed', figsize=(14, 7))
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))
#ax.xaxis.set_major_locator(MonthLocator(interval=2))
pred_uc.predicted_mean.plot(ax=ax, label='Forecast')
ax.fill_between(pred_ci.index,
pred_ci.iloc[:, 0],
pred_ci.iloc[:, 1], color='k', alpha=.25)
ax.set_xlabel('Date')
ax.set_ylabel('MOS Wind Speed')
#add the LT monthly average to plot
from datetime import date
cm = date.today().month
lty = y.groupby(y.index.month).mean()
lty = lty.to_frame()
lty.columns=['LT Mean']
ltyc = lty.iloc[cm-1:12].reset_index() # extract curr month to end of LT mean monthly wind speed
#create date sequence using date format of df = y
ltyc['Date'] = pd.to_datetime(ltyc["Date"], format='%m').apply(lambda dt: dt.replace(year=2020))#convert the "Date" col to yyyy-mm-dd
ltycs = pd.Series(ltyc['LT Mean'].values, index=ltyc['Date'])#convert to Series since the other plots are in series format
ltycs.plot(label='LT Mean',ax=ax,color='k')
plt.grid(b=True, which='major', color='k', linestyle='-')
plt.grid(b=True, which='minor', color='g', linestyle='-', alpha=0.2)#alpha is the minor grid thickness w/higher numbers thicker lines
plt.minorticks_on()
plt.legend()
plt.show()
Here is my plot so far below. Than you for any help with this!

Matplotlib: Assign legend to different figures

Inside a loop I am calculating some things and then I want to plot them in two different figures. I have set up the figures as
susc_comp, (ax1,ax2) = plt.subplots( 2, 1, sharex=True, sharey='none', figsize=(8.3,11.7))
cole_cole, (ax3) = plt.subplots( 1, 1, sharex='none', sharey='none', figsize=(8.3,11.7))
for j,temp in enumerate(indexes_T[i]):
Calculate and plot in the corresponding ax1,ax2,ax3
plt.legend(loc=0, fontsize='small', numpoints = 1, ncol=(len(indexes_T[i]))/2, frameon=False)
susc_comp.savefig('suscp_components'+str(field)+'Oe.png', dpi=300)
cole_cole.savefig('Cole_Cole'+str(field)+'Oe.png', dpi=300)
But I get the legend only in the sus_comp figure (it is the same legend for both figures). How can I select the figure and add the legend to each of them?
Thank you very much!
You can call figure.legend directly (although I think this may have less functionality than plt.legend). Therefore, I would do this a different way.
The question states that both legends are the same. In addition, the second figure only has 1 axes in it. Therefore one solution would be to get the handles and labels from ax3, then manually apply those to both figures. A simplified example is below:
import matplotlib.pyplot as plt
susc_comp, (ax1, ax2) = plt.subplots(1,2)
cole_cole, ax3 = plt.subplots()
ax1.plot([1,2,3], label="Test1")
ax2.plot([3,2,1], label="Test2")
ax3.plot([1,2,3], label="Test1")
ax3.plot([3,2,1], label="Test2")
handles, labels = ax3.get_legend_handles_labels()
ax2.legend(handles, labels, loc=1, fontsize='small', numpoints = 1)
ax3.legend(handles, labels, loc=1, fontsize='small', numpoints = 1)
plt.show()
This gives the following 2 figures:

how to add variable error bars to scatter plot points with shared axes in python matplotlib

I have generated a plot that shows a topographic profile with points along the profile that represent dated points. However, these dated points also have symmetric uncertainty values/error bars (that typically vary for each point).
In this example, I treat non-dated locations as 'np.nan'. I would like to add uncertainty values to the y2 axis (Mean Age) with defined uncertainty values as y2err.
Everytime I use the ax2.errorbar( ... ) line, my graph is squeezed and distorted.
import numpy as np
import matplotlib.pyplot as plt
fig, ax1 = plt.subplots()
#Longitude = x; Elevation = y
x = (-110.75696,-110.75668,-110.75640,-110.75612,-110.75584,-110.75556,-110.75528)
y = (877,879,878,873,871,872,872)
ax1.plot(x, y)
ax1.set_xlabel('Longitude')
# Make the y-axis label, ticks and tick labels match the line color.
ax1.set_ylabel('Elevation', color='b')
ax1.tick_params('y', colors='b')
ax2 = ax1.twinx()
# Mean Age, np.nan = 0.0
y2 = (np.nan,20,np.nan,np.nan,np.nan,np.nan,np.nan)
y2err = (np.nan,5,np.nan,np.nan,np.nan,np.nan,np.nan)
ax2.scatter(x, y2, color='r')
#add error bars to scatter plot points
# (??????) ax2.errorbar(x, y, y2, y2err, capsize = 0, color='black')
ax2.set_ylim(10,30)
ax2.set_ylabel('Mean Age', color='r')
ax2.tick_params('y', colors='r')
fig.tight_layout()
plt.show()
If I do not apply the ax2.errorbar... line my plot looks like the first image, which is what I want but with the points showing uncertainty values (+/- equal on both side of point in the y-axis direction).
Plot of Elevation vs Age without error bars
When I use the ax2.errorbar line it looks like the second image:
Plot when using ax2.errorbar line
Thanks!