简体   繁体   中英

Gradient 2D plot using contourf

I did a test code brigging something I saw on stack on different topic, and try to assemble it to make what I need: a filled curve with gradient.

After validate this test code I will make a subplot (4 plots for 4 weeks) with the same min/max for all plot (it's a power consumption).

My code:

from matplotlib import pyplot as plt
import numpy as np

# random x
x = range(100)

# smooth random y
y = 0
result = []
for _ in x:
    result.append(y)
    y += np.random.normal(loc=0, scale=1)#, size=len(x))
y = result    
y = list(map(abs, y))


# creation of z for contour
z1 = min(y)
z3 = max(y)/(len(x)+1)
z2 = max(y)-z3
z = [[z] * len(x) for z in np.arange(z1,z2,z3)]


num_bars = len(x)  # more bars = smoother gradient

# plt.contourf(x, y, z, num_bars, cmap='greys')
plt.contourf(x, y, z, num_bars, cmap='cool', levels=101)

background_color = 'w'
plt.fill_between(
    x, 
    y, 
    y2=max(y), 
    color=background_color
    )

But everytime I make the code run, the result display a different gradient scale, that is not smooth neither even straight right. AND sometime the code is in error: TypeError: Length of y (100) must match number of rows in z (101)

在此处输入图像描述 在此处输入图像描述

I'm on it since too many time, turning around, and can't figure where I'm wrong...

I finally find something particularly cool, how to:

  • have both filled gradient curves in a different color (thanks to JohanC in this topic )
  • use x axis with datetime (thanks to Ffisegydd in this topic )

Here the code:

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import matplotlib.dates as mdates




np.random.seed(2022)

st_date = '2022-11-01 00:00:00'
st_date = pd.to_datetime(st_date)
en_date = st_date + pd.DateOffset(days=7)
x = pd.date_range(start=st_date,end=en_date,freq='30min')
x = mdates.date2num(x)

y = np.random.normal(0.01, 1, len(x)).cumsum()

fig, ax = plt.subplots(figsize=(18, 5))
ax.plot(x, y, color='grey')


########################
# positives fill
#######################

grad1 = ax.imshow(
    np.linspace(0, 1, 256).reshape(-1, 1),
    cmap='Blues',
    vmin=-0.5,
    aspect='auto',
    extent=[x.min(), x.max(), 0, y.max()],
    # extent=[x[0], x[1], 0, y.max()],
    origin='lower'
    )

poly_pos = ax.fill_between(x, y.min(), y, alpha=0.1)

grad1.set_clip_path(
    poly_pos.get_paths()[0],
    transform=ax.transData
    )

poly_pos.remove()

########################
# negatives fill
#######################

grad2 = ax.imshow(
    np.linspace(0, 1, 256).reshape(-1, 1),
    cmap='Reds',
    vmin=-0.5,
    aspect='auto',
    extent=[x.min(), x.max(), y.min(), 0],
    origin='upper'
    )

poly_neg = ax.fill_between(x, y, y.max(), alpha=0.1)

grad2.set_clip_path(
    poly_neg.get_paths()[0],
    transform=ax.transData
    )

poly_neg.remove()


########################
# decorations and formatting plot
########################

ax.xaxis_date()
date_format = mdates.DateFormatter('%d-%b %H:%M')
ax.xaxis.set_major_formatter(date_format)
fig.autofmt_xdate()
ax.grid(True)

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM