I have the following code for a Matplotlib plot:
import pandas as pd
from matplotlib import pyplot as plt
columns = ['Price']
price_values = [[4.2],
[4.1],
[4],
[3.8],
[3.9],
[4.2],
[4.5],
[4.8],
[5.2],
[5.2],
[5.2],
[5.6],
[5.2],
[5.1],
[5.3],
[6],
[6.2],
[6.3],
[6.2],
[6],
[5.5] ,
[5.2],
[4.8],
[4.6]]
price_data = pd.DataFrame(price_values, index=range(0, 24), columns=columns)
fig = plt.figure(linewidth=1, figsize=(9, 5))
ax=plt.gca()
for column,color in zip(price_data.columns,['gold']):
ax.fill_between(
x=price_data.index,
y1=price_data[column],
y2=0,
label=column,
color=color,
alpha=.5,
step='post',
linewidth=5,
)
ax.set_facecolor("white")
ax.set_xlabel("Time of day", fontsize = 14, labelpad=8)
ax.set_ylabel("Price [Cent/kWh]", fontsize = 14,labelpad=8)
ax.set_xlim(0, 23)
ax.set_ylim(0, 8)
plt.xticks(price_data.index, labels=[f'{h:02d}:00' for h in price_data.index], rotation=90)
plt.tight_layout()
hours = list(range(25))
labels = [f'{h:02d}:00' for h in hours]
ax.tick_params(axis='both', which='major', labelsize=14)
ax.legend(loc='center left', bbox_to_anchor=(0.15, 1.07), fontsize = 14, ncol=3)
plt.savefig('Diagramm.png', edgecolor='black', dpi=400, bbox_inches='tight')
plt.show()
Now I would like to remove the area under the curve, sucht that I can only see the curve. I tried to use
plt.bar(fill=False)
but I get the error "TypeError: bar() missing 2 required positional arguments: 'x' and 'height'". Any suggestions how I can do that
CodePudding user response:
Using fill_between
and later remove the area under the curve seems like a pretty convoluted way to plot your data. But you could just set y2=price_data[column]
:
price_data = pd.DataFrame(price_values, index=range(0, 24), columns=columns)
fig = plt.figure(linewidth=1, figsize=(9, 5))
ax=plt.gca()
for column,color in zip(price_data.columns,['gold']):
ax.fill_between(
x=price_data.index,
y1=price_data[column],
y2=price_data[column],
label=column,
color=color,
alpha=.5,
step='post',
linewidth=5,
)
ax.set_facecolor("white")
ax.set_xlabel("Time of day", fontsize = 14, labelpad=8)
ax.set_ylabel("Price [Cent/kWh]", fontsize = 14,labelpad=8)
ax.set_xlim(0, 23)
ax.set_ylim(0, 8)
plt.xticks(price_data.index, labels=[f'{h:02d}:00' for h in price_data.index], rotation=90)
plt.tight_layout()
hours = list(range(25))
labels = [f'{h:02d}:00' for h in hours]
ax.tick_params(axis='both', which='major', labelsize=14)
ax.legend(loc='center left', bbox_to_anchor=(0.15, 1.07), fontsize = 14, ncol=3)
plt.savefig('Diagramm.png', edgecolor='black', dpi=400, bbox_inches='tight')
plt.show()
Edit: @JohanC rightfully noted that the last value barely appears on the plot. One way to avoid this would be to replace your loop with the following:
price_data.plot(ax=ax, color="gold", drawstyle="steps-mid", linewidth=2)
CodePudding user response:
Note that your solution is missing the last price value, the one between 23 and 24 h. You'll need to repeat the last value for this to work. To draw a step plot, the easiest way is ax.step
.
The following example code changes the values for the first and the last value to make them stand out more.
from matplotlib import pyplot as plt
import pandas as pd
columns = ['Price']
price_values = [[1.2], [4.1], [4], [3.8], [3.9], [4.2], [4.5], [4.8], [5.2], [5.2], [5.2], [5.6], [5.2], [5.1], [5.3], [6], [6.2], [6.3], [6.2], [6], [5.5], [5.2], [4.8], [1.6]]
price_data = pd.DataFrame(price_values, index=range(0, 24), columns=columns)
fig, ax = plt.subplots(figsize=(9, 5))
for column, color in zip(price_data.columns, ['gold']):
ax.step(x=range(len(price_data) 1), y=list(price_data[column]) list(price_data[column][-1:]),
where='post', color=color, linewidth=5, label=column)
ax.set_xlabel("Time of day", fontsize=14, labelpad=8)
ax.set_ylabel("Price [Cent/kWh]", fontsize=14, labelpad=8)
ax.set_xlim(0, 24)
ax.set_ylim(0, 8)
xs = range(len(price_data) 1)
ax.set_xticks(xs, labels=[f'{h:02d}:00' for h in xs], rotation=90)
ax.tick_params(axis='both', which='major', labelsize=14)
ax.legend(loc='lower left', bbox_to_anchor=(0.15, 1.01), fontsize=14, ncol=3)
plt.tight_layout()
plt.savefig('Diagramm.png', edgecolor='black', dpi=400, bbox_inches='tight')
plt.show()
Alternatively, you could use Seaborn's histplot
, which has a step option (element='step', fill=False
), but that works easiest if you'd let seaborn do the counting for the histogram. You could use sns.histplot
's weights=
parameter to fill in the values, e.g.
sns.histplot(x=price_data.index, weights=price_data[column].values, bins=len(price_data), binrange=(0, 24),
element='step', fill=False, color=color, linewidth=5, label=column, ax=ax)