问题
I have a dataset whose uncertainty I would like to represent as a filled region around the main plot. The errors are large in the x-axes direction, so I have not been able to use plt.fill_between(x, y1, y2)
, which requires a common set of x-axes.
I have tried using plt.fill(np.append(x1, x2[::-1]))
as suggested elsewhere on this website, but because my data zigzags up and down a lot, the filled regions end up looking like nodes (see attached figure).
What I would like to accomplish is a point-to-point filling, i.e., filling the region between the i-th value of the lower bound and the i-th value of the upper bound for every value of i, such that main line with the actual data is always within the filled region..
The code I'm currently using is attached below. Thanks in advance for your advice/help!
import numpy as np
import matplotlib.pyplot as plt
# Generate data
data = [ # 1st set
np.asarray([[7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147],
[0.95655418,0.968751302,0.983557511,1,0.990592677,0.97449496,0.95440505,0.924954671,0.886996122,0.82251848,0.778125913,0.73916151,0.700254675,0.668987694,0.63055911,0.590810638,0.555342043,0.507765573,0.4616611,0.429145607,0.413109798,0.390302561,0.363457831,0.342211112,0.318108912,0.294919636,0.2604157,0.234729394,0.215631188,0.19881722,0.183199438,0.16849855,0.155955983,0.139366571,0.130774073,0.122769502,0.113845958,0.108554715,0.100988871,0.096328988,0.089256135,0.084745413,0.079921355,0.074552516,0.069711584,0.065973993,0.063518416,0.060676971,0.057921448,0.054652475,0.052496131,0.049222527,0.046675798,0.044500797,0.043952159,0.041155119,0.043656139,0.040926506,0.039692837,0.037439469,0.036360189,0.035155463,0.033663854,0.032398257,0.03094279,0.029410186,0.028667612,0.02746653,0.026438134,0.025641696,0.024370006,0.023830637,0.023306691,0.021891054,0.020939248,0.019839459,0.019218755,0.019261568,0.019029851,0.018123198,0.01710584,0.016715688,0.01618066,0.015785562,0.014618372,0.013970195,0.013450019,0.0130316,0.012526295,0.012519175,0.0111811,0.010592157,0.010524284,0.010147982,0.010100317,0.009651263,0.009243377,0.009168683,0.008427179,0.008649776,0.00849209,0.008433903,0.008057094,0.007496825,0.007536894,0.007522125,0.007019614,0.007308734,0.006747738,0.006585782,0.006723507,0.006146523,0.005883389,0.006014114,0.005708983,0.005689707,0.00532408,0.005527866,0.00545286,0.004954855,0.004833038,0.004554934,0.004251427,0.004186365,0.004252841,0.003897866,0.003731514,0.003545388,0.003436594,0.003431516,0.003253962,0.002831155,0.002969271,0.001684758,0.001340519,0.001385708,0.001303324,0.001303421,0.001044814,0.001077059,0.001093969]]),
# 2nd set
np.asarray([[7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95],
[0.914033852,0.950504849,0.80004654,0.695783944,0.662746701,0.695576344,0.90154606,1,0.81140764,0.678474576,0.634939708,0.607590316,0.518639178,0.207727727,0.216432158,0.224586428,0.279720169,0.245618979,0.222696026,0.199679098,0.179142946,0.158946171,0.14188248,0.127260706,0.112782138,0.100888414,0.089853204,0.08216043,0.073372773,0.067958601,0.061487526,0.055911548,0.050893264,0.046562233,0.042915263,0.039707178,0.036378441,0.033371983,0.030817107,0.028757013,0.026475762,0.024725777,0.022679087,0.020535423,0.019044371,0.017906946,0.016977675,0.016137162,0.015026638,0.013821426,0.012863647,0.011716813,0.011141965,0.010609055,0.00977254,0.009348052,0.008344767,0.007617324,0.007495344,0.006615654,0.006292315,0.006144333,0.005258415,0.004866276,0.004712482,0.004014683,0.004069901,0.00361893,0.003229981,0.003008768,0.003020642,0.00285177,0.00227489,0.002182672,0.001804809,0.001610111,0.001768367,0.001669851,0.001623464,0.001456057,0.001114707,0.0011109,0.001091451,0.001165129,0.000900596,0.000952285,0.000960306,0.000922442,0.000836143]]),
# 3rd set
np.asarray([[5,6,7,8,9,10,11,12,13,14,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40],
[1,0.927662075,0.96202778,0.924335135,0.828600389,0.613168998,0.434280748,0.33575471,0.226712113,0.179613025,0.094097102,0.132828886,0.183557076,0.139710035,0.101280635,0.07329473,0.056400289,0.043787685,0.033451036,0.026281189,0.019311693,0.015875145,0.014837602,0.012488443,0.011285327,0.009343611,0.008602607,0.007826083,0.006956754,0.005454963,0.005808192]]),
# 4th set
np.asarray([[6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365],
[0.885909672,1,0.99162113,0.872488779,0.87398788,0.805963959,0.74319068,0.726634486,0.740202316,0.730969223,0.670578511,0.624200235,0.613225969,0.575205857,0.609029515,0.597698204,0.57980882,0.576631664,0.581497131,0.593804795,0.606824276,0.640333687,0.634379114,0.656129569,0.663956949,0.634547791,0.595586735,0.581772148,0.569338853,0.555159526,0.545101106,0.525147065,0.502896746,0.497743379,0.493600401,0.49762563,0.477230369,0.482063433,0.477360682,0.467838442,0.467380429,0.47560526,0.468880058,0.487816836,0.480472169,0.467176897,0.460125843,0.448287451,0.437142557,0.42658121,0.413663556,0.408012163,0.402944298,0.395960648,0.392914203,0.385336533,0.382498637,0.380576939,0.375302121,0.372433499,0.372657596,0.371524779,0.367985585,0.366572768,0.368253803,0.371552111,0.378665281,0.384730649,0.391524758,0.393310424,0.400383444,0.412549566,0.419823185,0.429974348,0.443500171,0.467968688,0.476722667,0.480154755,0.485114033,0.49532665,0.491100296,0.487384531,0.48849776,0.495426176,0.495257257,0.481092465,0.436619122,0.408269466,0.374306761,0.373166502,0.382555796,0.378342072,0.346950265,0.317572698,0.252999696,0.153670297,0.136906858,0.128124111,0.118055812,0.11413037,0.110161997,0.10628067,0.098298601,0.093111985,0.088350851,0.08576681,0.079879986,0.074838647,0.072270659,0.068716759,0.066169679,0.065067294,0.064145231,0.061806894,0.060669599,0.059005956,0.057686128,0.05512712,0.053881379,0.052239032,0.051214915,0.050582681,0.049530671,0.048884795,0.051156767,0.049774256,0.0514431,0.05146419,0.051118524,0.050911102,0.049803011,0.049447797,0.048438409,0.048405349,0.046723778,0.046154424,0.04552512,0.044032249,0.043395595,0.043308933,0.042585152,0.041754058,0.040325688,0.039175667,0.039162313,0.037457688,0.037956389,0.037296581,0.036296388,0.035926523,0.035588571,0.034830947,0.035225701,0.034703098,0.033922258,0.033755366,0.033411962,0.032572077,0.032549764,0.032282915,0.032172298,0.031884569,0.031313459,0.031114445,0.031373301,0.031243683,0.031569485,0.030555099,0.031135214,0.031321489,0.030749573,0.029966772,0.03061446,0.030135384,0.030585367,0.029686435,0.02988313,0.029481707,0.02910797,0.029261633,0.029571263,0.029690859,0.028788667,0.028728067,0.028809428,0.029128161,0.028235243,0.02782359,0.027672193,0.027629457,0.027277172,0.027107321,0.026965431,0.026783799,0.026939647,0.026590097,0.026175666,0.026194135,0.025958189,0.025875979,0.026209379,0.02533026,0.025988519,0.025428073,0.018142192,0.018212207,0.017783734,0.017665953,0.017192459,0.016945588,0.016437243,0.016641711,0.016239232,0.016401381,0.015912438,0.016196707,0.016107538,0.015733245,0.015514499,0.015532215,0.015836562,0.015428837,0.0157516,0.014978627,0.014932577,0.014423966,0.014887073,0.014867981,0.014573822,0.014581828,0.014697673,0.014533383,0.014405806,0.014522672,0.014052074,0.014218667,0.014169407,0.014463344,0.014302986,0.013865811,0.013956405,0.014048572,0.013790196,0.014130022,0.014036684,0.014114657,0.014071971,0.013703234,0.013826223,0.013563827,0.013678588,0.013383205,0.013217588,0.013010951,0.012847964,0.013262616,0.013069786,0.013113281,0.013071785,0.012477441,0.012546062,0.012646679,0.012860151,0.012243156,0.012315449,0.012518825,0.012396436,0.012397889,0.012489189,0.012442466,0.012540196,0.012643484,0.01227506,0.012253067,0.011976709,0.012023984,0.011997722,0.012033947,0.012080226,0.012191508,0.011918882,0.011854949,0.011518262,0.011825999,0.011507567,0.011218112,0.011136758,0.010964953,0.011244613,0.011005658,0.010895433,0.011235724,0.010974862,0.010672335,0.010636289,0.010645618,0.010843378]])]
# Generate color set
color_set = ["blue",
"red",
"green",
"orange"]
# Create figure to plot data in
plt.figure(figsize=(4, 3)).add_axes([0.1,
0.1,
0.8,
0.8])
# Iterate through data and plot it
for i in range(0, len(data)):
d = data[i]
# Create lists
x = d[0] * 6
y = d[1]
x_err = 0.1 * x
y_err = 0.01 * y
# Set lower and upper bounds for error region
x_lo = x - x_err
x_hi = x + x_err
y_lo = y - y_err
y_hi = y + y_err
# Set color
color = color_set[i]
# Plot lines
plt.plot(x, y,
linestyle="-",
linewidth=1.0,
marker="o",
markersize=2,
color=color)
"""
PYPLOT FILL
This method involves filling an area defined by the high and low errors in
the x and y axes directions. However, regions of overlap appear darker in
colour, which is not ideal
# Generate shaded region of uncertainty
plt.fill(np.append(x_lo, x_hi[::-1]),
np.append(y_lo, y_hi[::-1]),
color=color,
linewidth=0.0,
alpha=0.5)
"""
"""
SHAPELY POLYGON
This method was introduced by @William Miller on StackExchange, and makes use
of the "shapely" Python module. A polygon describing the region of error is
first defined for each point, and the polygons are then merged together and
the region is filled
"""
for k in range(1, len(d)):
# Check to see what the polygon is like
"""
Not all the regions in this method overlap
area = geometry.Polygon([(x_lo[k - 1], y_lo[k - 1]),
(x_lo[k], y_lo[k]),
(x_hi[k], y_lo[k]),
(x_hi[k], y_hi[k]),
(x_hi[k - 1], y_hi[k - 1]),
(x_lo[k - 1], y_hi[k - 1])])
"""
"""
# Polygon describing error around each point
area1 = geometry.Polygon([(x_lo[k - 1], y[k - 1]),
(x[k - 1], y_lo[k - 1]),
(x_hi[k - 1], y[k - 1]),
(x[k - 1], y_hi[k - 1])])
area2 = geometry.Polygon([(x_lo[k], y[k]),
(x[k], y_lo[k]),
(x_hi[k], y[k]),
(x[k], y_hi[k])])
# Polygon bridging the two points
area3 = geometry.Polygon([(x_lo[k - 1], y[k - 1]),
(x_lo[k], y[k]),
(x_hi[k], y[k]),
(x_hi[k - 1], y[k - 1])])
area4 = geometry.Polygon([(x[k - 1], y_lo[k - 1]),
(x[k], y_lo[k]),
(x[k], y_hi[k]),
(x[k - 1], y_hi[k - 1])])
area = cascaded_union([area1, area2, area3, area4])
area_x, area_y = area.exterior.xy
plt.gca().add_patch(patches.Polygon(np.stack([area_x, area_y], 1),
facecolor=color,
alpha=0.2))
"""
err_shaded = []
for k in range(1, len(d)):
# Polygon defining error region for each point
area1 = geometry.Polygon([(x_lo[k - 1], y[k - 1]),
(x[k - 1], y_lo[k - 1]),
(x_hi[k - 1], y[k - 1]),
(x[k - 1], y_hi[k - 1])])
area2 = geometry.Polygon([(x_lo[k], y[k]),
(x[k], y_lo[k]),
(x_hi[k], y[k]),
(x[k], y_hi[k])])
# Polygon bridging the two points
# Bridge along x errors
area3 = geometry.Polygon([(x_lo[k - 1], y[k - 1]),
(x_lo[k], y[k]),
(x_hi[k], y[k]),
(x_hi[k - 1], y[k - 1])])
# Bridge along y errors
area4 = geometry.Polygon([(x[k - 1], y_lo[k - 1]),
(x[k], y_lo[k]),
(x[k], y_hi[k]),
(x[k - 1], y_hi[k - 1])])
# Merge the areas together
area = cascaded_union([area1, area2, area3, area4])
# Append the shaded error region for this point to the list
err_shaded.append(area)
err_shaded = cascaded_union(err_shaded)
area_x, area_y = err_shaded.exterior.xy
plt.gca().add_patch(patches.Polygon(np.stack([area_x, area_y], 1),
facecolor=color,
alpha=0.2))
plt.savefig(r"test_plot_err_shaded.png",
figsize=(4, 3),
dpi=300)
plt.close()
回答1:
Is this more like what you're looking for?
You can create this by breaking the polygons that get filled with plt.fill()
into smaller pieces of the x_lo
, x_hi
, y_lo
, and y_hi
arrays and filling each segment separately like this
from matplotlib.colors import to_rgb
color = to_rgb(color_set[i])
for k in range(1, len(x), 1):
xe = [x_lo[k], x_lo[k-1], x_hi[k-1], x_hi[k]]
ye = [y_lo[k], y_lo[k-1], y_hi[k-1], y_hi[k]]
plt.fill(xe, ye, fc=(color[0], color[1], color[2], 0.3))
This isn't really the best way to go about this but it might work well enough for your purposes. A slightly more robust approach is to create a cascaded union using shapely.ops.cascaded_union,
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import to_rgb
from matplotlib import patches
from shapely.ops import cascaded_union
from shapely import geometry
# Unchanged code omitted
for i in range(0, len(data)):
# Unchanged code omitted
# Set color
color = to_rgb(color_set[i])
color = (color[0], color[1], color[2], 0.3)
# Plot lines
plt.plot(x, y, linestyle="-", linewidth=1.0, marker="o", markersize=2, color=color)
# Plot region of error
polygons = list()
for k in range(1, len(x), 1):
polygons.append(geometry.Polygon([(x_lo[k], y_lo[k]), (x_lo[k-1], y_lo[k-1]),
(x_hi[k-1], y_hi[k-1]), (x_hi[k], y_hi[k])]))
boundary = cascaded_union(polygons)
x, y = boundary.exterior.xy
ax.add_patch(patches.Polygon(np.stack([x, y], 1), fc=color))
plt.show()
which will give you something that looks like this
来源:https://stackoverflow.com/questions/59200776/python-3-7-fill-area-between-two-lines-with-different-x-axes-values-that-zigzag