Home > Net >  How to remove area under the curve in matplotlib
How to remove area under the curve in matplotlib

Time:12-10

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()

Output: enter image description here

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()

ax.step

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)
  • Related