VanessaF
VanessaF

Reputation: 793

Round lines in Matplotlib

I would like to have a diagramm in Matplotlib with a curved (smooth) lines. So the individual points should be connected by round lines. Further, I would like to have no values on the y-line (only the description). Here is the coode:

from matplotlib import pyplot as plt
%matplotlib inline

load = [0.0, 0.1, 0.5, 0.7, 0.4, 0.55, 0.4, 0.3, 0.4, 0.5, 0.65, 0.75, 0.768, 0.75, 0.65, 0.5, 0.4, 0.3, 0.2, 0.15, 0.25, 0.4, 0.5, 0.4, 0.5]    
hours = list(range(25)) # [0, 1, 2, ... 22, 23, 24]
labels = [f'{h:02d}:00' for h in hours] # ["00:00", "01:00", ... "23:00", "24:00"]

fig = plt.figure(linewidth=1, figsize=(9, 5))
ax = plt.gca()


ax.plot(hours, load, color="goldenrod",drawstyle="default",  linewidth=3) # <- drawstyle argument.
ax.set_xlabel("Time of day", fontsize=14, labelpad=8)
ax.set_ylabel("Electrical power in W", fontsize=14, labelpad=8)
ax.set_xlim(0, 24)
ax.set_ylim(0, 1)    
plt.xticks(hours, labels=labels, rotation=90)

ax.tick_params(axis='both', which='major', labelsize=0)
# (Optional) ax.legend(loc='center left', bbox_to_anchor=(0.03, 1.15), fontsize = 14, ncol=3)
plt.tight_layout() # This must be called last, after all elements (plot and legend) are ready.
for item in [fig, ax]:
    item.patch.set_visible(False)
plt.savefig('CS_Curtailment_ElectricalLoad_NoFrame.png', edgecolor='black', dpi=400, bbox_inches='tight')
plt.show()

I think the attribute "drawystyle" might be changed. But I do not know how. I'd appreciate every comment and would be thankful for your help.

Upvotes: 1

Views: 979

Answers (2)

Shmn
Shmn

Reputation: 703

from matplotlib import pyplot as plt
from scipy.interpolate import interp1d
import numpy as np
load = [0.0, 0.1, 0.5, 0.7, 0.4, 0.55, 0.4, 0.3, 0.4, 0.5, 0.65, 0.75, 0.768, 0.75, 0.65, 0.5, 0.4, 0.3, 0.2, 0.15, 0.25, 0.4, 0.5, 0.4, 0.5]
hours = list(range(25)) # [0, 1, 2, ... 22, 23, 24]
labels = [f'{h:02d}:00' for h in hours] # ["00:00", "01:00", ... "23:00", "24:00"]


f = interp1d(hours, load)
f2 = interp1d(hours, load, kind='cubic')

xnew = np.linspace(0, 24, num=500, endpoint=True)

plt.xticks(np.arange(0, 25, step=1))  # Set label locations.
plt.xticks(np.arange(25), labels)  # Set text labels.
plt.xticks(np.arange(25), labels, rotation=90)

plt.plot(hours, load, 'o', xnew, f(xnew), '-', xnew, f2(xnew), '--')
plt.legend(['data', 'linear', 'cubic'], loc='best')
plt.ylabel("Electrical power in W", fontsize=14, labelpad=8)
plt.xlabel("Time of day", fontsize=14, labelpad=8)
plt.show()


plt.xticks(np.arange(0, 25, step=1))  # Set label locations.
plt.xticks(np.arange(25), labels)  # Set text labels.
plt.xticks(np.arange(25), labels, rotation=90)

plt.plot(xnew, f2(xnew), color="green", linewidth=3)
plt.legend(['cubic'], loc='best')
plt.ylabel("Electrical power in W", fontsize=14, labelpad=8)
plt.xlabel("Time of day", fontsize=14, labelpad=8)
plt.show()

Edit-1: x-axis labels are 90 degree rotated

Plotting figure using cubic interpolation: enter image description here enter image description here

Edit-2: To hide to y-axis variables, we can add plt.tick_params(labelleft=False) before plt.show(). Plotted figure is shown below: enter image description here

Edit-3: Plotting new load.

We can plot new load list by adding these lines into the code.

load_2 = [0.0, 0.3, 0.2, 0.8, 0.1, 0.5, 0.2, 0.7, 0.4, 0.5, 0.34, 0.45, 0.768, 0.9, 0.25, 0.55, 0.2, 0.3, 0.2, 0.65, 0.25, 0.4, 0.2, 0.4, 0.5]
f3 = interp1d(hours, load_2, kind='cubic', fill_value="extrapolate")
xnew = np.linspace(0, 24, num=500, endpoint=True)

plt.xticks(np.arange(0, 25, step=1))  # Set label locations.
plt.xticks(np.arange(25), labels)  # Set text labels.
plt.xticks(np.arange(25), labels, rotation=90)


plt.plot(xnew, f3(xnew), color="red", linewidth=3)
plt.legend(['cubic'], loc='best')
plt.ylabel("Electrical power in W", fontsize=14, labelpad=8)
plt.xlabel("Time of day", fontsize=14, labelpad=8)
plt.tick_params(labelleft=False)
plt.show()

Edit-4: Plotting two lines in one figure:

xnew = np.linspace(0, 24, num=500, endpoint=True)
plt.xticks(np.arange(0, 25, step=1))  # Set label locations.
plt.xticks(np.arange(25), labels)  # Set text labels.
plt.xticks(np.arange(25), labels, rotation=90)


plt.plot(xnew, f2(xnew), color="blue", linewidth=3)
plt.plot(xnew, f3(xnew), color="red", linewidth=3)

plt.legend(['load-1', 'load-2'], loc='best')
plt.ylabel("Electrical power in W", fontsize=14, labelpad=8)
plt.xlabel("Time of day", fontsize=14, labelpad=8)
plt.tick_params(labelleft=False)
plt.show()

enter image description here Edit-5: To fill the area under curve of the two lines, we need to add following lines:

plt.fill_between(xnew, f2(xnew), color="blue", alpha=0.30, edgecolor=None)
plt.fill_between(xnew, f3(xnew), color="red", alpha=0.30, edgecolor=None)

Plotted figure is shown below: enter image description here

Upvotes: 3

r-beginners
r-beginners

Reputation: 35115

I don't have any experience with curve fitting, but I've looked at customizing it based on this answer. np.polyfit(x,y, deg)

from matplotlib import pyplot as plt
import numpy as np
%matplotlib inline

load = [0.0, 0.1, 0.5, 0.7, 0.4, 0.55, 0.4, 0.3, 0.4, 0.5, 0.65, 0.75, 0.768, 0.75, 0.65, 0.5, 0.4, 0.3, 0.2, 0.15, 0.25, 0.4, 0.5, 0.4, 0.5]    
hours = list(range(25)) # [0, 1, 2, ... 22, 23, 24]
labels = [f'{h:02d}:00' for h in hours] # ["00:00", "01:00", ... "23:00", "24:00"]

poly = np.polyfit(hours, load, 8)
poly_y = np.poly1d(poly)(hours)

fig = plt.figure(linewidth=1, figsize=(9, 5))
ax = plt.gca()

# ax.plot(hours, load, color="goldenrod", ls='-', linewidth=3) # <- drawstyle argument.
ax.plot(hours, poly_y, color="goldenrod", ls='-', linewidth=3)
ax.set_xlabel("Time of day", fontsize=14, labelpad=8)
ax.set_ylabel("Electrical power in W", fontsize=14, labelpad=8)
ax.set_xlim(0, 24)
ax.set_ylim(0, 1)    
ax.set_xticks(hours)
ax.set_xticklabels(labels, rotation=90)
ax.set_yticks([])
ax.tick_params(axis='both', which='major', labelsize=10)
# (Optional) ax.legend(loc='center left', bbox_to_anchor=(0.03, 1.15), fontsize = 14, ncol=3)
plt.tight_layout() # This must be called last, after all elements (plot and legend) are ready.
# for item in [fig, ax]:
#     item.patch.set_visible(False)
plt.savefig('CS_Curtailment_ElectricalLoad_NoFrame.png', edgecolor='black', dpi=400, bbox_inches='tight')
plt.show()

enter image description here

Upvotes: 0

Related Questions