flipping and rotating numpy arrays for contour plots - python

Short Version:
I have a 10x10 numpy array whose contour plot (plotted with pyplot.contourf) looks like this
Now, I want it look something like this - assuming the plot is symmetric across X and Y axes.
Long version
I have a 10x10 numpy array z as a function of x and y. where x=y=np.arange(0.002,0.022,0.002). Here is what I tried
import numpy as np
import matplotlib.pyplot as plt
z=np.array([[ 2.08273679, -0.06591932, -1.14525488, -1.49923222, -1.74361248,
-1.81418446, -1.90115591, -1.94329043, -1.93130228, -1.96064259],
[ 0.20180514, -0.94522815, -1.34635828, -1.58844515, -1.7528935 ,
-1.84438752, -1.86257547, -1.9439332 , -1.99009407, -1.94829146],
[-1.09749238, -1.48234452, -1.64234357, -1.75344742, -1.83019763,
-1.88547473, -1.92958533, -1.940775 , -1.95535063, -1.9629588 ],
[-1.62892483, -1.70176401, -1.76263555, -1.84966414, -1.87139241,
-1.91879916, -1.90796703, -1.96632612, -1.95794984, -1.94585536],
[-1.71551518, -1.91806287, -1.86999609, -1.90800839, -1.92515012,
-1.93386969, -1.96487487, -1.95405297, -1.97032435, -1.96087146],
[-1.81904322, -1.94790171, -2. , -1.96932249, -1.91842475,
-1.98101775, -1.98521938, -1.97618539, -1.95892852, -2.01410874],
[-1.8138236 , -1.90877811, -1.93966404, -1.98406259, -1.95253807,
-1.95867436, -1.96679456, -2.01126218, -1.99885932, -1.99369292],
[-1.9927308 , -1.97658099, -1.91586737, -1.96813381, -1.98416011,
-1.98639893, -1.99997964, -1.99746813, -1.98126505, -1.97767361],
[-1.96406473, -1.92609437, -1.99171257, -1.94687523, -1.9823819 ,
-1.97786533, -2.02323228, -1.98559114, -1.99172681, -2.00881064],
[-1.92470024, -1.99537152, -1.99419303, -1.97261023, -1.9673841 ,
-1.98801505, -2.02412735, -2.01394008, -2.01956817, -2.04963448]])
x=y=np.arange(0.002,0.022,0.002)
#The following gives the plot I currently have
plt.figure()
plt.contourf(x,y,z)
plt.show()
#Tried to flip the matrix z using np.flipud and np.fliplr
plt.figure()
plt.contourf(x,y,z)
plt.contourf(-x,y,np.fliplr(z))
plt.contourf(x,-y,np.flipud(z))
plt.contourf(-x,-y,np.flipud(np.fliplr(z)))
plt.show()
#Also tried to rotate the matrix z using np.rot90
plt.figure()
plt.contourf(x,y,z)
plt.contourf(x,-y,np.rot90(z))
plt.contourf(-x,-y,np.rot90(z,2))
plt.contourf(-x,y,np.rot90(z,3))
plt.show()
I get the following plots with the above code
and
Ideally I would also like to fill the discontinuity at the origin by interpolation of the plot. But for starters, would like to get the orientation right. Any help is greatly appreciated.

Your problem is that, even though you negate x and y, their order stays the same, so with negative x, you go from -0.002 to -0.022, which means that the flipped z gets flipped back during the plotting. To achieve what you want, you can do the following:
#either don't flip z
plt.figure()
plt.contourf(x,y,z)
plt.contourf(-x,y,z)
plt.contourf(x,-y,z)
plt.contourf(-x,-y,z)
plt.show()
#or reverse also -x and -y:
plt.figure()
plt.contourf(x,y,z)
plt.contourf(-x[::-1],y,np.fliplr(z))
plt.contourf(x,-y[::-1],np.flipud(z))
plt.contourf(-x[::-1],-y[::-1],np.flipud(np.fliplr(z)))
plt.show()
If you would have just concatenated z and the flipped z, everything would have worked as expected. plt.contourf takes care of the interpolation itself.
ztotal = np.concatenate([np.fliplr(z),z],axis=1)
ztotal = np.concatenate([np.flipud(ztotal),ztotal],axis=0)
xtotal = np.concatenate([-x[::-1],x],axis=0)
ytotal = np.concatenate([-y[::-1],y],axis=0)
plt.figure()
plt.contourf(xtotal,ytotal,ztotal)
plt.show()

Combine results of fliplr and flipud of your array z to a new double sized array zz then plot it. You have to skip x and y in interval (-0.002; +0.002) with nan values according to your first figure:
import numpy as np
import matplotlib.pyplot as plt
z=np.array([[ 2.08273679, -0.06591932, -1.14525488, -1.49923222, -1.74361248,
-1.81418446, -1.90115591, -1.94329043, -1.93130228, -1.96064259],
[ 0.20180514, -0.94522815, -1.34635828, -1.58844515, -1.7528935 ,
-1.84438752, -1.86257547, -1.9439332 , -1.99009407, -1.94829146],
[-1.09749238, -1.48234452, -1.64234357, -1.75344742, -1.83019763,
-1.88547473, -1.92958533, -1.940775 , -1.95535063, -1.9629588 ],
[-1.62892483, -1.70176401, -1.76263555, -1.84966414, -1.87139241,
-1.91879916, -1.90796703, -1.96632612, -1.95794984, -1.94585536],
[-1.71551518, -1.91806287, -1.86999609, -1.90800839, -1.92515012,
-1.93386969, -1.96487487, -1.95405297, -1.97032435, -1.96087146],
[-1.81904322, -1.94790171, -2. , -1.96932249, -1.91842475,
-1.98101775, -1.98521938, -1.97618539, -1.95892852, -2.01410874],
[-1.8138236 , -1.90877811, -1.93966404, -1.98406259, -1.95253807,
-1.95867436, -1.96679456, -2.01126218, -1.99885932, -1.99369292],
[-1.9927308 , -1.97658099, -1.91586737, -1.96813381, -1.98416011,
-1.98639893, -1.99997964, -1.99746813, -1.98126505, -1.97767361],
[-1.96406473, -1.92609437, -1.99171257, -1.94687523, -1.9823819 ,
-1.97786533, -2.02323228, -1.98559114, -1.99172681, -2.00881064],
[-1.92470024, -1.99537152, -1.99419303, -1.97261023, -1.9673841 ,
-1.98801505, -2.02412735, -2.01394008, -2.01956817, -2.04963448]])
x=y=np.linspace(-0.020,0.020,21)
zz = np.empty((21,21)); zz[:,:] = np.nan
zz[11:,11:] = z
zz[11:,:10] = np.fliplr(z)
zz[:10,:] = np.flipud(zz[11:,:])
plt.figure()
plt.contourf(x,y,zz)
plt.show()
To fill the gap skip one point of coordinate arrays:
...
x=y=np.linspace(-0.020,0.020,20)
zz = np.empty((20,20)); zz[:,:] = np.nan
zz[10:,10:] = z
zz[10:,:10] = np.fliplr(z)
zz[:10,:] = np.flipud(zz[10:,:])
...

Related

Radial Heatmap from data sheet

I have a file with 3 columns of data: Zenith (Z, from 0 to 90°) and Azimuth (A, from 0 to 360°). And radiance as the color variable.
I need to use python with matplotlib to plot this data into something resembling this:
This is my code so far (it returns an error):
import matplotlib.pyplot as plt
import numpy as np
# `data` has the following shape:
# [
# [Zenith value going from 0 to 90],
# [Azimuth values (0 to 365) increasing by 1 and looping back after 365],
# [radiance: floats that need to be mapped by the color value]
#]
data = [[6.000e+00 1.200e+01 1.700e+01 2.300e+01 2.800e+01 3.400e+01 3.900e+01
4.500e+01 5.000e+01 5.600e+01 6.200e+01 6.700e+01 7.300e+01 7.800e+01
8.400e+01 8.900e+01 3.934e+01 4.004e+01 4.054e+01 4.114e+01 4.154e+01
4.204e+01 4.254e+01 4.294e+01 4.334e+01 4.374e+01 4.414e+01 4.454e+01
4.494e+01 4.534e+01 4.564e+01 4.604e+01 4.644e+01 4.684e+01 4.714e+01
4.754e+01 4.794e+01 4.824e+01 4.864e+01 4.904e+01 4.944e+01 4.984e+01
5.014e+01 5.054e+01 5.094e+01 5.134e+01 5.174e+01 5.214e+01 5.264e+01
5.304e+01 5.344e+01 5.394e+01 5.444e+01 5.494e+01 5.544e+01 5.604e+01
5.674e+01 5.764e+01]
[1.960e+02 3.600e+01 2.360e+02 7.600e+01 2.760e+02 1.160e+02 3.160e+02
1.560e+02 3.560e+02 1.960e+02 3.600e+01 2.360e+02 7.600e+01 2.760e+02
1.160e+02 3.160e+02 6.500e+00 3.400e+00 3.588e+02 2.500e+00 3.594e+02
3.509e+02 5.000e-01 6.900e+00 1.090e+01 3.478e+02 1.250e+01 1.050e+01
7.300e+00 2.700e+00 3.571e+02 3.507e+02 1.060e+01 3.200e+00 3.556e+02
3.480e+02 7.300e+00 3.597e+02 3.527e+02 1.260e+01 6.600e+00 1.200e+00
3.570e+02 3.538e+02 3.520e+02 3.516e+02 3.528e+02 3.560e+02 1.200e+00
8.800e+00 3.567e+02 1.030e+01 6.800e+00 8.300e+00 3.583e+02 3.581e+02
3.568e+02 3.589e+02]
[3.580e-04 6.100e-04 3.220e-04 4.850e-04 4.360e-04 2.910e-04 1.120e-03
2.320e-04 4.300e-03 2.680e-04 1.700e-03 3.790e-04 7.460e-04 8.190e-04
1.030e-03 3.650e-03 3.050e-03 3.240e-03 3.340e-03 3.410e-03 3.490e-03
3.290e-03 3.630e-03 3.510e-03 3.320e-03 3.270e-03 3.280e-03 3.470e-03
3.720e-03 3.960e-03 3.980e-03 3.700e-03 3.630e-03 4.100e-03 4.080e-03
3.600e-03 3.990e-03 4.530e-03 4.040e-03 3.630e-03 4.130e-03 4.370e-03
4.340e-03 4.210e-03 4.100e-03 4.090e-03 4.190e-03 4.380e-03 4.460e-03
4.080e-03 4.420e-03 3.960e-03 4.230e-03 4.120e-03 4.440e-03 4.420e-03
4.370e-03 4.380e-03]]
rad = data[0]
azm = data[1]
# From what I understand, I need to create a meshgrid from the zenith and azimuth values
r, th = np.meshgrid(rad, azm)
z = data[2] # This doesn't work as `pcolormesh` expects this to be a 2d array
plt.subplot(projection="polar")
plt.pcolormesh(th, r, z, shading="auto")
plt.plot(azm, r, color="k", ls="none")
plt.show()
Note: my actual data goes on for 56k lines and looks like this (Ignore the 4th column):
The example data above is my attempt to reduce the resolution of this massive file, so I only used 1/500 of the lines of data. This might be the wrong way to reduce the resolution, please correct me if it is!
Every tutorial I've seen generate the z value from the r array generated by meshgrid. This is leaving me confused about how I would convert my z column into a 2d array that would properly map to the zenith and azimuth values.
They'll use something like this:
z = (r ** 2.0) / 4.0
So, taking the exact shape of r and applying a transformation to create the color.
The solution was in the data file all along. I needed to better understand what np.meshrid actually did. Turns out the data already is a 2d array, it just needed to be reshaped. I also found a flaw in the file, fixing it reduced its lines from 56k to 15k. This was small enough that I did not need to reduce the resolution.
Here's how I reshaped my data, and what the solution looked like:
import matplotlib.pyplot as plt
import numpy as np
with open("data.txt") as f:
lines = np.array(
[
[float(n) for n in line.split("\t")]
for i, line in enumerate(f.read().splitlines())
]
)
data = [np.reshape(a, (89, 180)) for a in lines.T]
rad = np.radians(data[1])
azm = data[0]
z = data[2]
plt.subplot(projection="polar")
plt.pcolormesh(rad, azm, z, cmap="coolwarm", shading="auto")
plt.colorbar()
plt.show()
The simplest way to plot the given data is with a polar scatter plot.
Using blue for low values and red for high values, it could look like:
import matplotlib.pyplot as plt
import numpy as np
data = [[6.000e+00, 1.200e+01, 1.700e+01, 2.300e+01, 2.800e+01, 3.400e+01, 3.900e+01, 4.500e+01, 5.000e+01, 5.600e+01, 6.200e+01, 6.700e+01, 7.300e+01, 7.800e+01, 8.400e+01, 8.900e+01, 3.934e+01, 4.004e+01, 4.054e+01, 4.114e+01, 4.154e+01, 4.204e+01, 4.254e+01, 4.294e+01, 4.334e+01, 4.374e+01, 4.414e+01, 4.454e+01, 4.494e+01, 4.534e+01, 4.564e+01, 4.604e+01, 4.644e+01, 4.684e+01, 4.714e+01, 4.754e+01, 4.794e+01, 4.824e+01, 4.864e+01, 4.904e+01, 4.944e+01, 4.984e+01, 5.014e+01, 5.054e+01, 5.094e+01, 5.134e+01, 5.174e+01, 5.214e+01, 5.264e+01, 5.304e+01, 5.344e+01, 5.394e+01, 5.444e+01, 5.494e+01, 5.544e+01, 5.604e+01, 5.674e+01, 5.764e+01],
[1.960e+02, 3.600e+01, 2.360e+02, 7.600e+01, 2.760e+02, 1.160e+02, 3.160e+02, 1.560e+02, 3.560e+02, 1.960e+02, 3.600e+01, 2.360e+02, 7.600e+01, 2.760e+02, 1.160e+02, 3.160e+02, 6.500e+00, 3.400e+00, 3.588e+02, 2.500e+00, 3.594e+02, 3.509e+02, 5.000e-01, 6.900e+00, 1.090e+01, 3.478e+02, 1.250e+01, 1.050e+01, 7.300e+00, 2.700e+00, 3.571e+02, 3.507e+02, 1.060e+01, 3.200e+00, 3.556e+02, 3.480e+02, 7.300e+00, 3.597e+02, 3.527e+02, 1.260e+01, 6.600e+00, 1.200e+00, 3.570e+02, 3.538e+02, 3.520e+02, 3.516e+02, 3.528e+02, 3.560e+02, 1.200e+00, 8.800e+00, 3.567e+02, 1.030e+01, 6.800e+00, 8.300e+00, 3.583e+02, 3.581e+02, 3.568e+02, 3.589e+02],
[3.580e-04, 6.100e-04, 3.220e-04, 4.850e-04, 4.360e-04, 2.910e-04, 1.120e-03, 2.320e-04, 4.300e-03, 2.680e-04, 1.700e-03, 3.790e-04, 7.460e-04, 8.190e-04, 1.030e-03, 3.650e-03, 3.050e-03, 3.240e-03, 3.340e-03, 3.410e-03, 3.490e-03, 3.290e-03, 3.630e-03, 3.510e-03, 3.320e-03, 3.270e-03, 3.280e-03, 3.470e-03, 3.720e-03, 3.960e-03, 3.980e-03, 3.700e-03, 3.630e-03, 4.100e-03, 4.080e-03, 3.600e-03, 3.990e-03, 4.530e-03, 4.040e-03, 3.630e-03, 4.130e-03, 4.370e-03, 4.340e-03, 4.210e-03, 4.100e-03, 4.090e-03, 4.190e-03, 4.380e-03, 4.460e-03, 4.080e-03, 4.420e-03, 3.960e-03, 4.230e-03, 4.120e-03, 4.440e-03, 4.420e-03, 4.370e-03, 4.380e-03]]
rad = np.radians(data[1])
azm = data[0]
z = data[2]
plt.subplot(projection="polar")
plt.scatter(rad, azm, c=z, cmap='coolwarm')
plt.colorbar()
plt.show()
Creating such a scatter plot with your real data gives an idea how it looks like. You might want to choose a different colormap, depending on what you want to convey. You also can choose a smaller dot size (for example plt.scatter(rad, azm, c=z, cmap='plasma', s=1, ec='none')) if there would be too many points.
A simple way to create a filled image from non-gridded data uses tricontourf with 256 colors (it looks quite dull with the given data, so I didn't add an example plot):
plt.subplot(projection="polar")
plt.tricontourf(rad, azm, z, levels=256, cmap='coolwarm')

Question about plotting a 2D array in python

I have a question regarding the plotting of a 2D array with matplotlib. In my code, I have a 2D array named z of len(z) = 20 , and z has the values :
[[ 642.3774486 662.59980588 706.80142179 764.78786911 831.67963477
904.67872269 982.01426528 1062.49208551 1145.27029231 1229.73549967
1315.42936618 1402.00251422 1489.18433714 1576.7625077 1664.56866033
1752.46813939 1840.35250424 1928.13395024 2015.74109019 2103.11572013]
[ 554.60565024 560.31827232 591.87923587 638.51633542 695.03697015
758.44479983 826.83191468 898.90395242 973.74278531 1050.67523901
1129.19496311 1208.91328775 1289.52693752 1370.79606051 1452.52883572
1534.57042218 1616.79485775 1699.09901217 1781.39800199 1863.6216653 ]
[ 484.80770831 476.01059519 494.93090638 530.21865818 576.36816197
630.18473341 689.62342052 753.28967576 820.18913475 889.58883479
960.93441647 1033.79791772 1107.84339435 1182.80346976 1258.46286755
1334.64656142 1411.2110677 1488.03793055 1565.02877024 1642.1014669 ]
[ 432.98362283 409.67677451 415.95643334 439.89483737 475.67321023
519.89852343 570.3887828 625.64925554 684.60934062 746.47628701
810.64772628 876.65640413 944.13370762 1012.78473545 1082.37075581
1152.6965571 1223.60113409 1294.95070536 1366.63339492 1438.55512495]
[ 399.13339379 361.31681026 354.95581673 367.54487301 392.95211493
427.58616989 469.12800152 515.98269176 567.00340294 621.33759567
678.33489253 737.48874699 798.39787733 860.73985757 924.25250052
988.72040921 1053.96505692 1119.83733661 1186.21187604 1252.98263943]
[ 383.25702119 330.93070245 311.92905657 313.16876508 328.20487607
353.24767279 385.84107667 424.28998442 467.37132169 514.17276077
563.99591521 616.29494628 670.63590348 726.66883614 784.10810167
842.71811777 902.30283619 962.6978243 1023.76421361 1085.38401036]
[ 385.35450503 318.51845109 286.87615284 276.7665136 281.43149365
296.88303213 320.52800827 350.57113352 385.71309689 424.98178231
467.63079434 513.07500201 560.84778607 610.57167115 661.93755925
714.68968276 768.6144719 823.53216843 879.29040761 935.75923772]
[ 405.4258453 324.08005616 279.79710556 258.33811855 252.63196767
258.49224791 273.18879631 294.82613906 322.02872853 353.76466029
389.23952991 427.82891418 469.0335251 512.44836259 557.74087328
604.6351042 652.89996405 702.340369 752.79045805 804.10832153]
[ 443.47104202 347.61551768 290.69191471 257.88357994 241.80629812
238.07532013 243.82344079 257.05500104 276.3182166 300.52139471
328.82212191 360.55668279 395.19312056 432.29891048 471.51804375
512.55438207 555.15931264 599.12242601 644.26436494 690.43126177]
[ 499.49009518 389.12483563 319.56058031 275.40289778 248.95448502
235.63224878 232.43194171 237.25771947 248.58156112 265.25198557
286.37857036 311.25830784 339.32657247 370.12331481 403.26907065
438.44751639 475.39251767 513.87833946 553.71212826 594.72805845]
[ 573.48300477 448.60801002 366.40310234 310.89607205 274.07652836
251.16303388 239.01429907 235.43429433 238.81876207 247.95643287
261.90887525 279.93378933 301.43388082 325.92157557 352.993954
382.31450714 413.59957914 446.60810935 481.13374802 516.99871158]
[ 665.44977081 526.06504086 431.21948081 364.36310276 317.17242814
284.66767542 263.57051287 251.58472563 247.02981947 248.63473661
255.41303657 266.58312726 281.51504561 299.69369278 320.69269378
344.15535434 369.78049705 397.31173568 426.52922422 457.24322114]
[ 775.39039329 621.49592813 514.00971573 435.80398992 378.24218436
336.1461734 306.10058311 285.70901337 273.2147333 267.28689679
266.89105434 271.20632163 279.57006684 291.43966643 306.36529001
323.97005797 343.9352714 365.98921845 389.89855687 415.46158715]
[ 903.3048722 734.90067184 614.77380708 525.21873351 457.28579702
405.59852782 366.60450978 337.80715755 317.37350358 303.91291341
296.34292854 293.80337244 295.5989445 301.15949651 310.01174267
321.75861805 336.06390219 352.64055766 371.24174595 391.65380959]
[1049.19320756 866.27927199 733.51175488 632.60733354 554.30326611
493.02473868 445.0822929 407.87915817 379.50613029 358.51278647
343.76865919 334.37427969 329.60167861 328.85318304 331.63205178
337.52103456 346.16638942 357.26575331 370.55879147 385.81988847]
[1213.05539936 1015.63172859 870.22355911 757.96979001 669.29459165
598.42480597 541.53393246 495.92501523 459.61261345 431.08651597
409.16824628 392.91904338 381.57826916 374.520726 371.22621733
371.25730752 374.24273309 379.8648054 387.84969343 397.9598238 ]
[1394.89144759 1182.95804162 1024.90921978 901.30610293 802.25977363
721.79872971 655.95942846 601.94472873 557.69295304 521.63410191
492.5416898 469.43766351 451.52871614 438.16212541 428.79423931
422.96743691 420.2929332 420.43771393 423.11445184 428.07361556]
[1594.70135227 1368.25821109 1197.5687369 1062.61627228 953.19881205
863.14650989 788.3587809 725.93829867 673.74714907 630.15554429
593.88898977 563.93014008 539.45301957 519.77738125 504.33611774
492.65142275 484.31698975 478.9844789 476.35306668 476.16126376]
[1812.48511338 1571.532237 1388.20211045 1241.90029807 1122.11170691
1022.46814651 938.73198977 867.90572504 807.77520155 756.65084311
713.21014617 676.39647309 645.35117944 619.36649354 597.8518526
580.30926502 566.31490274 555.50510031 547.56553796 542.22276841]
[2048.24273094 1792.78011936 1596.80934044 1439.1581803 1308.9984582
1199.76363956 1107.07905509 1027.84700786 959.77711046 901.11999837
850.50515902 806.83666254 769.22319574 736.92946227 709.34144391
685.94096373 666.28667217 649.99957816 636.75186568 626.25812949]]
I wanted to plot the first 20 set of data of z, so z[0] against my other variable M. I did the following:
M = np.arange(15.5,16.5, 0.05)
plt.plot(M, Z[0], label = r'$\chi^2$ for $\Omega_m[0] $ ')
and it gave me the folllwing plot (ignore the label whith color blue, there were 2 same datas plotted and only one label) :
Then I tried the following code, which gave me the other pic.
plt.plot(M, Z[0:20], label = r'$\chi^2$ for$\Omege_m = 0$ ')
But I don't understand why, with the same data, the shape of the function is obviously different between the two pics. Could anyone explain me why the second image is different from the first one, and what does it plot exactly ? How does matplotlib plot a 2D array ?
And if i can explain a bit the background of z, it is a function that depends on 2 parameters, M and Omega_M, Omega_m = np.arange(0.0, 1.0, 0.05) (len(Omega_m) =20) and z[0] corresponds to the 20 values of the Z function for each value of Omega_m and for M[0], z1 correspond of the 20 values of the Z function for each values of Omega_m for M1 etc, until the function is calculated for each value of each parameter.
First, let's explain why the two graphs differ. Because in the first graph, you're plotting the first row of Z with M. In the second graph, you're drawing the columns of Z with M. And this became so clear when I tried to plot the first three columns of Z:
plt.plot(M, Z[:, 0], label = r'$\chi^2$ for $\Omega_m[0] $ ')
plt.plot(M, Z[:, 1], label = r'$\chi^2$ for $\Omega_m[0] $ ')
plt.plot(M, Z[:, 2], label = r'$\chi^2$ for $\Omega_m[0] $ ')
plt.show()
Which produced this graph:
And that makes total sense as it will throw an error when I pass Z with one less row:
plt.plot(M, Z[0:19], label = r'$\chi^2$ for $\Omega_m[0] $ ')
ValueError: x and y must have same first dimension, but have shapes (20,) and (19, 20)
So, to produce 20 curves that match the rows of Z, not the columns, you need to transpose your Z array using Z.T notation like so:
plt.plot(M, Z.T, label = r'$\chi^2$ for $\Omega_m[0] $ ')
plt.show()
Which will get this graph:

How to convert A[x,y] = z to [ [ x0...xN ], [ y0...yN], [ z0...zN] ]

I have a 2D Numpy array that represents an image, and I want to create a surface plot of image intensity using matplotlib.surface_plot. For this function, I need to convert the 2D array A[x,y] => z into three arrays: [x0,...,xN], [y0,...,yN] and [z0,...,zN]. I can see how to do this conversion element-by-element:
X = []
Y = []
Z = []
for x in range( A.shape[ 0 ] ):
for y in range( A.shape[ 1 ] ):
X.append( x )
Y.append( y )
Z.append( A[x,y] )
but I'm wondering whether there is a more Pythonic way to do this?
a very simple way to do this could be to basically use the code shown in the matplotlib example. assuming x and y representing the sizes of the two dims in your image array A, you could do
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
# generate some input data that looks nice on a color map:
A = np.mgrid[0:10:0.1,0:10:0.1][0]
X = np.arange(0, A.shape[0], 1)
Y = np.arange(0, A.shape[1], 1)
X, Y = np.meshgrid(X, Y)
fig = plt.figure()
ax = fig.gca(projection='3d')
surf = ax.plot_surface(X, Y, A, cmap='viridis',
linewidth=0, antialiased=False)
gives
You possibly don't need to construct the actual grid, because some pyplot functions accept 1d arrays for x and y, implying that a grid is to be constructed. It seems that Axes3D.plot_surface (which I presume you meant) does need 2d arrays as input, though.
So to get your grid the easiest way is using np.indices to get the indices corresponding to your array:
>>> import numpy as np
...
... # dummy data
... A = np.random.random((3,4)) # randoms of shape (3,4)
...
... # get indices
... x,y = np.indices(A.shape) # both arrays have shape (3,4)
...
... # prove that the indices correspond to the values of A
... print(all(A[i,j] == A[x[i,j], y[i,j]] for i in x.ravel() for j in y.ravel()))
True
The resulting arrays all have the same shape as A, which should be correct for most use cases. If for any reason you really need a flattened 1d array, you should use x.ravel() etc. to get a flattened view of the same 2d array.
I should note though that the standard way to visualize images (due to the short-wavelength variation of the data) is pyplot.imshow or pyplot.pcolormesh which can give you pixel-perfect visualization, albeit in two dimensions.
We agree X, Y and Z have different sizes (N for X and Y and N^2 for Z) ? If yes:
X looks not correct (you add several times the same values)
something like:
X = list(range(A.shape[0])
Y = list(range(A.shape[1])
Z = [A[x,y] for x in X for y in Y]

How to uniformly resample a non-uniform signal using SciPy?

I have an (x, y) signal with non-uniform sample rate in x. (The sample rate is roughly proportional to 1/x). I attempted to uniformly re-sample it using scipy.signal's resample function. From what I understand from the documentation, I could pass it the following arguments:
scipy.resample(array_of_y_values, number_of_sample_points, array_of_x_values)
and it would return the array of
[[resampled_y_values],[new_sample_points]]
I'd expect it to return an uniformly sampled data with a roughly identical form of the original, with the same minimal and maximalx value. But it doesn't:
# nu_data = [[x1, x2, ..., xn], [y1, y2, ..., yn]]
# with x values in ascending order
length = len(nu_data[0])
resampled = sg.resample(nu_data[1], length, nu_data[0])
uniform_data = np.array([resampled[1], resampled[0]])
plt.plot(nu_data[0], nu_data[1], uniform_data[0], uniform_data[1])
plt.show()
blue: nu_data, orange: uniform_data
It doesn't look unaltered, and the x scale have been resized too. If I try to fix the range: construct the desired uniform x values myself and use them instead, the distortion remains:
length = len(nu_data[0])
resampled = sg.resample(nu_data[1], length, nu_data[0])
delta = (nu_data[0,-1] - nu_data[0,0]) / length
new_samplepoints = np.arange(nu_data[0,0], nu_data[0,-1], delta)
uniform_data = np.array([new_samplepoints, resampled[0]])
plt.plot(nu_data[0], nu_data[1], uniform_data[0], uniform_data[1])
plt.show()
What is the proper way to re-sample my data uniformly, if not this?
Please look at this rough solution:
import matplotlib.pyplot as plt
from scipy import interpolate
import numpy as np
x = np.array([0.001, 0.002, 0.005, 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 20])
y = np.exp(-x/3.0)
flinear = interpolate.interp1d(x, y)
fcubic = interpolate.interp1d(x, y, kind='cubic')
xnew = np.arange(0.001, 20, 1)
ylinear = flinear(xnew)
ycubic = fcubic(xnew)
plt.plot(x, y, 'X', xnew, ylinear, 'x', xnew, ycubic, 'o')
plt.show()
That is a bit updated example from scipy page. If you execute it, you should see something like this:
Blue crosses are initial function, your signal with non uniform sampling distribution. And there are two results - orange x - representing linear interpolation, and green dots - cubic interpolation. Question is which option you prefer? Personally I don't like both of them, that is why I usually took 4 points and interpolate between them, then another points... to have cubic interpolation without that strange ups. That is much more work, and also I can't see doing it with scipy, so it will be slow. That is why I've asked about size of the data.

Wrap around continuous colormap in matplotlib [duplicate]

I'm looking for a good circular/cyclic colormap to represent phase angle information (where the values are restricted to the range [0, 2π] and where 0 and 2π represent the same phase angle).
Background: I'd like to visualize normal modes by plotting both the power spectral density and the relative phase information of the oscillations across the system.
I'll admit that previously I used the 'rainbow' colormap for the power plot and the 'hsv' colormap for the phase plot (see [1]). However, the use of the rainbow colormap is extremely discouraged because of its lack of perceptual linearity and ordering [2][3]. So I switched to the 'coolwarm' colormap for the power plot which I quite like. Unfortunately, the 'hsv' colormap seems to introduce the same kind of visual distortions as the 'rainbow' map (and it also doesn't go along very well with the 'coolwarm' map since it looks kind of ugly and flashy in comparison).
Does anyone have a good recommendation for an alternative circular colormap which I could use for the phase plots?
Requirements:
It needs to be circular so that the values 0 and 2π are represented by the same color.
It should not introduce any visual distortions; in particular, it should be perceptually linear (which the 'hsv' colormap doesn't seem to be). I don't believe that perceptual ordering is such a big deal for phase information, but it would of course not do any harm.
It should be visually appealing when combined with the 'coolwarm' colormap. However, I'm not dead set on 'coolwarm' and am happy to consider other options if there is another nice pair of colormaps to visualize amplitude and phase information.
Bonus points if the colormap is available (or can be easily created) for use in matplotlib.
Many thanks for any suggestions!
[1] http://matplotlib.org/examples/color/colormaps_reference.html
[2] http://www.renci.org/~borland/pdfs/RainbowColorMap_VisViewpoints.pdf
[3] http://medvis.org/2012/08/21/rainbow-colormaps-what-are-they-good-for-absolutely-nothing/
As of matplotlib version 3.0 there are built-in cyclic perceptually uniform colormaps. OK, just the one colormap for the time being, but with two choices of start and end along the cycle, namely twilight and twilight_shifted.
A short example to demonstrate how they look:
import matplotlib.pyplot as plt
import numpy as np
# example data: argument of complex numbers around 0
N = 100
re, im = np.mgrid[-1:1:100j, -1:1:100j]
angle = np.angle(re + 1j*im)
cmaps = 'twilight', 'twilight_shifted'
fig, axs = plt.subplots(ncols=len(cmaps), figsize=(9.5, 5.5))
for cmap, ax in zip(cmaps, axs):
cf = ax.pcolormesh(re, im, angle, shading='gouraud', cmap=cmap)
ax.set_title(cmap)
ax.set_xlabel(r'$\operatorname{Re} z$')
ax.set_ylabel(r'$\operatorname{Im} z$')
ax.axis('scaled')
cb = plt.colorbar(cf, ax=ax, orientation='horizontal')
cb.set_label(r'$\operatorname{Arg} z$')
fig.tight_layout()
The above produces the following figure:
These brand new colormaps are an amazing addition to the existing collection of perceptually uniform (sequential) colormaps, namely viridis, plasma, inferno, magma and cividis (the last one was a new addition in 2.2 which is not only perceptually uniform and thus colorblind-friendly, but it should look as close as possible to colorblind and non-colorblind people).
EDIT: Matplotlib has now nice cyclic color maps, see the answer of #andras-deak below. They use a similar approach to the color maps as in this answer, but smooth the edges in luminosity.
The issue with the hue-HUSL colormap is that it's not intuitive to read an angle from it. Therefore, I suggest to make your own colormap. Here's a few possibilities:
For the linear segmented colormap, we definine a few colors. The colormap is then a linear interpolation between the colors. This has visual distortions.
For the luminosity-HSLUV map, we use the HUSL ("HSLUV") space, however instead of just hue channel, we use two colors and the luminosity channel. This has distortions in the chroma, but has bright colors.
The luminosity-HPLUV map, we use the HPLUV color space (following #mwaskom's comment). This is the only way to really have no visual distortions, but the colors are not saturated
This is what they look like:
We see that in our custom colormaps, white stands for 0, blue stands for 1i, etc.
On the upper right, we see the hue-HUSL map for comparison. There, the color-angle assignments are random.
Also when plotting a more complex function, it's straightforward to read out the phase of the result when using one of our colormaps.
And here's the code for the plots:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as col
import seaborn as sns
import hsluv # install via pip
import scipy.special # just for the example function
##### generate custom colormaps
def make_segmented_cmap():
white = '#ffffff'
black = '#000000'
red = '#ff0000'
blue = '#0000ff'
anglemap = col.LinearSegmentedColormap.from_list(
'anglemap', [black, red, white, blue, black], N=256, gamma=1)
return anglemap
def make_anglemap( N = 256, use_hpl = True ):
h = np.ones(N) # hue
h[:N//2] = 11.6 # red
h[N//2:] = 258.6 # blue
s = 100 # saturation
l = np.linspace(0, 100, N//2) # luminosity
l = np.hstack( (l,l[::-1] ) )
colorlist = np.zeros((N,3))
for ii in range(N):
if use_hpl:
colorlist[ii,:] = hsluv.hpluv_to_rgb( (h[ii], s, l[ii]) )
else:
colorlist[ii,:] = hsluv.hsluv_to_rgb( (h[ii], s, l[ii]) )
colorlist[colorlist > 1] = 1 # correct numeric errors
colorlist[colorlist < 0] = 0
return col.ListedColormap( colorlist )
N = 256
segmented_cmap = make_segmented_cmap()
flat_huslmap = col.ListedColormap(sns.color_palette('husl',N))
hsluv_anglemap = make_anglemap( use_hpl = False )
hpluv_anglemap = make_anglemap( use_hpl = True )
##### generate data grid
x = np.linspace(-2,2,N)
y = np.linspace(-2,2,N)
z = np.zeros((len(y),len(x))) # make cartesian grid
for ii in range(len(y)):
z[ii] = np.arctan2(y[ii],x) # simple angular function
z[ii] = np.angle(scipy.special.gamma(x+1j*y[ii])) # some complex function
##### plot with different colormaps
fig = plt.figure(1)
fig.clf()
colormapnames = ['segmented map', 'hue-HUSL', 'lum-HSLUV', 'lum-HPLUV']
colormaps = [segmented_cmap, flat_huslmap, hsluv_anglemap, hpluv_anglemap]
for ii, cm in enumerate(colormaps):
ax = fig.add_subplot(2, 2, ii+1)
pmesh = ax.pcolormesh(x, y, z/np.pi,
cmap = cm, vmin=-1, vmax=1)
plt.axis([x.min(), x.max(), y.min(), y.max()])
cbar = fig.colorbar(pmesh)
cbar.ax.set_ylabel('Phase [pi]')
ax.set_title( colormapnames[ii] )
plt.show()
You could try the "husl" system, which is similar to hls/hsv but with better visual properties. It is available in seaborn and as a standalone package.
Here's a simple example:
import numpy as np
from numpy import sin, cos, pi
import matplotlib.pyplot as plt
import seaborn as sns
n = 314
theta = np.linspace(0, 2 * pi, n)
x = cos(theta)
y = sin(theta)
f = plt.figure(figsize=(10, 5))
with sns.color_palette("husl", n):
ax = f.add_subplot(121)
ax.plot([np.zeros_like(x), x], [np.zeros_like(y), y], lw=3)
ax.set_axis_off()
ax.set_title("HUSL space")
with sns.color_palette("hls", n):
ax = f.add_subplot(122)
ax.plot([np.zeros_like(x), x], [np.zeros_like(y), y], lw=3)
ax.set_axis_off()
ax.set_title("HLS space")
f.tight_layout()
I just realized that cmocean has a colormap for this purpose.
import cmocean
import matplotlib.pyplot as plt
import numpy as np
azimuths = np.arange(0, 361, 1)
zeniths = np.arange(40, 70, 1)
values = azimuths * np.ones((30, 361))
fig, ax = plt.subplots(subplot_kw=dict(projection='polar'))
ax.pcolormesh(azimuths*np.pi/180.0, zeniths, values, cmap=cmocean.cm.phase)
ax.set_yticks([])
plt.show()
And the result is
I like the above color maps, but wanted to bootstrap some modern color theory into them. You can get a more perceptually uniform color space by using the CIECAM02 color space.
The colorspacious package is a nice one for converting into this great color space. Using this package, I bootstrapped the above answers into a custom cmap of my own.
from colorspacious import cspace_convert
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as col
import seaborn as sns
# first draw a circle in the cylindrical JCh color space.
# the third channel is hue in degrees. First is lightness and the second chroma
color_circle = np.ones((256,3))*60
color_circle[:,1] = np.ones((256))*45
color_circle[:,2] = np.arange(0,360,360/256)
color_circle_rgb = cspace_convert(color_circle, "JCh","sRGB1")
cm = col.ListedColormap(color_circle_rgb)
##### generate data grid like in above
N=256
x = np.linspace(-2,2,N)
y = np.linspace(-2,2,N)
z = np.zeros((len(y),len(x))) # make cartesian grid
for ii in range(len(y)):
z[ii] = np.arctan2(y[ii],x) # simple angular function
fig = plt.figure()
ax = plt.gca()
pmesh = ax.pcolormesh(x, y, z/np.pi,
cmap = cm, vmin=-1, vmax=1)
plt.axis([x.min(), x.max(), y.min(), y.max()])
cbar = fig.colorbar(pmesh)
cbar.ax.set_ylabel('Phase [pi]')
If you don't want to install the colorspacious package, you can just copy and paste this list of colors, and create a colormap directly:
colors = array([[0.91510904, 0.55114749, 0.67037311],
[0.91696411, 0.55081563, 0.66264366],
[0.91870995, 0.55055664, 0.65485881],
[0.92034498, 0.55037149, 0.64702356],
[0.92186763, 0.55026107, 0.63914306],
[0.92327636, 0.55022625, 0.63122259],
[0.9245696 , 0.55026781, 0.62326754],
[0.92574582, 0.5503865 , 0.6152834 ],
[0.92680349, 0.55058299, 0.6072758 ],
[0.92774112, 0.55085789, 0.59925045],
[0.9285572 , 0.55121174, 0.59121319],
[0.92925027, 0.551645 , 0.58316992],
[0.92981889, 0.55215808, 0.57512667],
[0.93026165, 0.55275127, 0.56708953],
[0.93057716, 0.5534248 , 0.55906469],
[0.93076407, 0.55417883, 0.55105838],
[0.93082107, 0.55501339, 0.54307696],
[0.93074689, 0.55592845, 0.53512681],
[0.9305403 , 0.55692387, 0.52721438],
[0.93020012, 0.55799943, 0.51934621],
[0.92972523, 0.55915477, 0.51152885],
[0.92911454, 0.56038948, 0.50376893],
[0.92836703, 0.56170301, 0.49607312],
[0.92748175, 0.56309471, 0.48844813],
[0.9264578 , 0.56456383, 0.48090073],
[0.92529434, 0.56610951, 0.47343769],
[0.92399062, 0.56773078, 0.46606586],
[0.92254595, 0.56942656, 0.45879209],
[0.92095971, 0.57119566, 0.4516233 ],
[0.91923137, 0.5730368 , 0.44456642],
[0.91736048, 0.57494856, 0.4376284 ],
[0.91534665, 0.57692945, 0.43081625],
[0.91318962, 0.57897785, 0.42413698],
[0.91088917, 0.58109205, 0.41759765],
[0.90844521, 0.58327024, 0.41120533],
[0.90585771, 0.58551053, 0.40496711],
[0.90312676, 0.5878109 , 0.3988901 ],
[0.90025252, 0.59016928, 0.39298143],
[0.89723527, 0.5925835 , 0.38724821],
[0.89407538, 0.59505131, 0.38169756],
[0.89077331, 0.59757038, 0.37633658],
[0.88732963, 0.60013832, 0.37117234],
[0.88374501, 0.60275266, 0.36621186],
[0.88002022, 0.6054109 , 0.36146209],
[0.87615612, 0.60811044, 0.35692989],
[0.87215369, 0.61084868, 0.352622 ],
[0.86801401, 0.61362295, 0.34854502],
[0.86373824, 0.61643054, 0.34470535],
[0.85932766, 0.61926872, 0.3411092 ],
[0.85478365, 0.62213474, 0.3377625 ],
[0.85010767, 0.6250258 , 0.33467091],
[0.84530131, 0.62793914, 0.3318397 ],
[0.84036623, 0.63087193, 0.32927381],
[0.8353042 , 0.63382139, 0.32697771],
[0.83011708, 0.63678472, 0.32495541],
[0.82480682, 0.63975913, 0.32321038],
[0.81937548, 0.64274185, 0.32174556],
[0.81382519, 0.64573011, 0.32056327],
[0.80815818, 0.6487212 , 0.31966522],
[0.80237677, 0.65171241, 0.31905244],
[0.79648336, 0.65470106, 0.31872531],
[0.79048044, 0.65768455, 0.31868352],
[0.78437059, 0.66066026, 0.31892606],
[0.77815645, 0.66362567, 0.31945124],
[0.77184076, 0.66657827, 0.32025669],
[0.76542634, 0.66951562, 0.3213394 ],
[0.75891609, 0.67243534, 0.32269572],
[0.75231298, 0.67533509, 0.32432138],
[0.74562004, 0.6782126 , 0.32621159],
[0.73884042, 0.68106567, 0.32836102],
[0.73197731, 0.68389214, 0.33076388],
[0.72503398, 0.68668995, 0.33341395],
[0.7180138 , 0.68945708, 0.33630465],
[0.71092018, 0.69219158, 0.33942908],
[0.70375663, 0.69489159, 0.34278007],
[0.69652673, 0.69755529, 0.34635023],
[0.68923414, 0.70018097, 0.35013201],
[0.6818826 , 0.70276695, 0.35411772],
[0.67447591, 0.70531165, 0.3582996 ],
[0.667018 , 0.70781354, 0.36266984],
[0.65951284, 0.71027119, 0.36722061],
[0.65196451, 0.71268322, 0.37194411],
[0.64437719, 0.71504832, 0.37683259],
[0.63675512, 0.71736525, 0.38187838],
[0.62910269, 0.71963286, 0.38707389],
[0.62142435, 0.72185004, 0.39241165],
[0.61372469, 0.72401576, 0.39788432],
[0.60600841, 0.72612907, 0.40348469],
[0.59828032, 0.72818906, 0.40920573],
[0.59054536, 0.73019489, 0.41504052],
[0.58280863, 0.73214581, 0.42098233],
[0.57507535, 0.7340411 , 0.42702461],
[0.5673509 , 0.7358801 , 0.43316094],
[0.55964082, 0.73766224, 0.43938511],
[0.55195081, 0.73938697, 0.44569104],
[0.54428677, 0.74105381, 0.45207286],
[0.53665478, 0.74266235, 0.45852483],
[0.52906111, 0.74421221, 0.4650414 ],
[0.52151225, 0.74570306, 0.47161718],
[0.5140149 , 0.74713464, 0.47824691],
[0.506576 , 0.74850672, 0.48492552],
[0.49920271, 0.74981912, 0.49164808],
[0.49190247, 0.75107171, 0.4984098 ],
[0.48468293, 0.75226438, 0.50520604],
[0.47755205, 0.7533971 , 0.51203229],
[0.47051802, 0.75446984, 0.5188842 ],
[0.46358932, 0.75548263, 0.52575752],
[0.45677469, 0.75643553, 0.53264815],
[0.45008317, 0.75732863, 0.5395521 ],
[0.44352403, 0.75816207, 0.54646551],
[0.43710682, 0.758936 , 0.55338462],
[0.43084133, 0.7596506 , 0.56030581],
[0.42473758, 0.76030611, 0.56722555],
[0.41880579, 0.76090275, 0.5741404 ],
[0.41305637, 0.76144081, 0.58104704],
[0.40749984, 0.76192057, 0.58794226],
[0.40214685, 0.76234235, 0.59482292],
[0.39700806, 0.7627065 , 0.60168598],
[0.39209414, 0.76301337, 0.6085285 ],
[0.38741566, 0.76326334, 0.6153476 ],
[0.38298304, 0.76345681, 0.62214052],
[0.37880647, 0.7635942 , 0.62890454],
[0.37489579, 0.76367593, 0.63563704],
[0.37126045, 0.76370246, 0.64233547],
[0.36790936, 0.76367425, 0.64899736],
[0.36485083, 0.76359176, 0.6556203 ],
[0.36209245, 0.76345549, 0.66220193],
[0.359641 , 0.76326594, 0.66873999],
[0.35750235, 0.76302361, 0.67523226],
[0.35568141, 0.76272903, 0.68167659],
[0.35418202, 0.76238272, 0.68807086],
[0.3530069 , 0.76198523, 0.69441305],
[0.35215761, 0.7615371 , 0.70070115],
[0.35163454, 0.76103888, 0.70693324],
[0.35143685, 0.76049114, 0.71310742],
[0.35156253, 0.75989444, 0.71922184],
[0.35200839, 0.75924936, 0.72527472],
[0.3527701 , 0.75855647, 0.73126429],
[0.3538423 , 0.75781637, 0.73718884],
[0.3552186 , 0.75702964, 0.7430467 ],
[0.35689171, 0.75619688, 0.74883624],
[0.35885353, 0.75531868, 0.75455584],
[0.36109522, 0.75439565, 0.76020396],
[0.36360734, 0.75342839, 0.76577905],
[0.36637995, 0.75241752, 0.77127961],
[0.3694027 , 0.75136364, 0.77670417],
[0.37266493, 0.75026738, 0.7820513 ],
[0.37615579, 0.74912934, 0.78731957],
[0.37986429, 0.74795017, 0.79250759],
[0.38377944, 0.74673047, 0.797614 ],
[0.38789026, 0.74547088, 0.80263746],
[0.3921859 , 0.74417203, 0.80757663],
[0.39665568, 0.74283455, 0.81243022],
[0.40128912, 0.74145908, 0.81719695],
[0.406076 , 0.74004626, 0.82187554],
[0.41100641, 0.73859673, 0.82646476],
[0.41607073, 0.73711114, 0.83096336],
[0.4212597 , 0.73559013, 0.83537014],
[0.42656439, 0.73403435, 0.83968388],
[0.43197625, 0.73244447, 0.8439034 ],
[0.43748708, 0.73082114, 0.84802751],
[0.44308905, 0.72916502, 0.85205505],
[0.44877471, 0.72747678, 0.85598486],
[0.45453694, 0.72575709, 0.85981579],
[0.46036897, 0.72400662, 0.8635467 ],
[0.4662644 , 0.72222606, 0.86717646],
[0.47221713, 0.72041608, 0.87070395],
[0.47822138, 0.71857738, 0.87412804],
[0.4842717 , 0.71671065, 0.87744763],
[0.4903629 , 0.71481659, 0.88066162],
[0.49649009, 0.71289591, 0.8837689 ],
[0.50264864, 0.71094931, 0.88676838],
[0.50883417, 0.70897752, 0.88965898],
[0.51504253, 0.70698127, 0.89243961],
[0.52126981, 0.70496128, 0.8951092 ],
[0.52751231, 0.70291829, 0.89766666],
[0.53376652, 0.70085306, 0.90011093],
[0.54002912, 0.69876633, 0.90244095],
[0.54629699, 0.69665888, 0.90465565],
[0.55256715, 0.69453147, 0.90675397],
[0.55883679, 0.69238489, 0.90873487],
[0.56510323, 0.69021993, 0.9105973 ],
[0.57136396, 0.68803739, 0.91234022],
[0.57761655, 0.68583808, 0.91396258],
[0.58385872, 0.68362282, 0.91546336],
[0.59008831, 0.68139246, 0.91684154],
[0.59630323, 0.67914782, 0.9180961 ],
[0.60250152, 0.67688977, 0.91922603],
[0.60868128, 0.67461918, 0.92023033],
[0.61484071, 0.67233692, 0.921108 ],
[0.62097809, 0.67004388, 0.92185807],
[0.62709176, 0.66774097, 0.92247957],
[0.63318012, 0.66542911, 0.92297153],
[0.63924166, 0.66310923, 0.92333301],
[0.64527488, 0.66078227, 0.92356308],
[0.65127837, 0.65844919, 0.92366082],
[0.65725076, 0.65611096, 0.92362532],
[0.66319071, 0.65376857, 0.92345572],
[0.66909691, 0.65142302, 0.92315115],
[0.67496813, 0.64907533, 0.92271076],
[0.68080311, 0.64672651, 0.92213374],
[0.68660068, 0.64437763, 0.92141929],
[0.69235965, 0.64202973, 0.92056665],
[0.69807888, 0.6396839 , 0.91957507],
[0.70375724, 0.63734122, 0.91844386],
[0.70939361, 0.63500279, 0.91717232],
[0.7149869 , 0.63266974, 0.91575983],
[0.72053602, 0.63034321, 0.91420578],
[0.72603991, 0.62802433, 0.9125096 ],
[0.7314975 , 0.62571429, 0.91067077],
[0.73690773, 0.62341425, 0.9086888 ],
[0.74226956, 0.62112542, 0.90656328],
[0.74758193, 0.61884899, 0.90429382],
[0.75284381, 0.6165862 , 0.90188009],
[0.75805413, 0.61433829, 0.89932181],
[0.76321187, 0.6121065 , 0.89661877],
[0.76831596, 0.6098921 , 0.89377082],
[0.77336536, 0.60769637, 0.89077786],
[0.77835901, 0.6055206 , 0.88763988],
[0.78329583, 0.6033661 , 0.88435693],
[0.78817477, 0.60123418, 0.88092913],
[0.79299473, 0.59912616, 0.87735668],
[0.79775462, 0.59704339, 0.87363986],
[0.80245335, 0.59498722, 0.86977904],
[0.8070898 , 0.592959 , 0.86577468],
[0.81166284, 0.5909601 , 0.86162732],
[0.81617134, 0.5889919 , 0.8573376 ],
[0.82061414, 0.58705579, 0.85290625],
[0.82499007, 0.58515315, 0.84833413],
[0.82929796, 0.58328538, 0.84362217],
[0.83353661, 0.58145389, 0.83877142],
[0.8377048 , 0.57966009, 0.83378306],
[0.8418013 , 0.57790538, 0.82865836],
[0.84582486, 0.57619119, 0.82339871],
[0.84977422, 0.57451892, 0.81800565],
[0.85364809, 0.57289 , 0.8124808 ],
[0.85744519, 0.57130585, 0.80682595],
[0.86116418, 0.56976788, 0.80104298],
[0.86480373, 0.56827749, 0.79513394],
[0.86836249, 0.56683612, 0.789101 ],
[0.87183909, 0.56544515, 0.78294645],
[0.87523214, 0.56410599, 0.77667274],
[0.87854024, 0.56282002, 0.77028247],
[0.88176195, 0.56158863, 0.76377835],
[0.88489584, 0.56041319, 0.75716326],
[0.88794045, 0.55929505, 0.75044023],
[0.89089432, 0.55823556, 0.74361241],
[0.89375596, 0.55723605, 0.73668312],
[0.89652387, 0.55629781, 0.72965583],
[0.89919653, 0.55542215, 0.72253414],
[0.90177242, 0.55461033, 0.71532181],
[0.90425 , 0.55386358, 0.70802274],
[0.90662774, 0.55318313, 0.70064098],
[0.90890408, 0.55257016, 0.69318073],
[0.91107745, 0.55202582, 0.68564633],
[0.91314629, 0.55155124, 0.67804225]])
cmap = col.ListedColormap(colors)
My CMasher package contains a large collection of scientific colormaps, including cyclic ones.
Unlike twilight, which comes close to being perceptually uniform, all of CMasher's colormaps are perceptually uniform sequential.
You can take a look at all of its colormaps in its online documentation.
CMasher's policy also states that if you are not satisfied with any of the colormaps it provides, you can request for me to create one for you that you like.

Categories