2

I want to create a plot that looks something like this which maps values to a user defined mesh size to represent a physical geometry.

enter image description here

I was looking for a way to create heatmaps and saw that seaborn has a function that creates heatmaps. The code below makes the heatmap, however, the mesh is equal size and does not represent the geometry that I want.

Here is the input.

import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

# Numpy arrays
IFE_x = np.array([7.11815 ,7.19875 ,7.34769 ,7.496   ,7.7413  ,
7.98354 , 8.22184 , 8.45534 , 8.77249 , 9.076   , 9.32338 ,
9.59487 , 9.84534 , 10.04127, 10.24567, 10.4217 , 10.54814,
10.63518, 10.70466, 10.74704, 10.77731])
IFE_x = np.repeat(IFE_x, 19)
IFE_y = np.array([24.90 ,24.40 , 23.40 , 22.40 , 21.00 ,16.00 , 11.00 ,6.00, 1.00,
-1.00 ,-6.00 ,-11.00,-16.00,-21.00,-22.40,-23.40,-24.40,-24.90,-25.40])
IFE_y = np.tile(IFE_y, 21)
IFE_ratio = np.array([1.0155, 0.9938, 0.9872, 0.9959, 1.0112, 0.9983,
1.0054, 0.9910, 1.0042, 0.9994, 1.0028, 1.0016, 1.0127, 1.0094, 1.0115,
0.9852, 0.9989, 0.9896, 0.9968, 1.0156, 0.9999, 0.9950, 1.0074, 0.9979,
0.9967, 1.0036, 0.9962, 1.0046, 0.9960, 1.0015, 1.0040, 1.0120, 1.0099,
1.0138, 1.0059, 1.0341, 0.9593, 1.0268, 0.9871, 0.9954, 0.9994, 1.0217,
0.9832, 1.0012, 1.0040, 1.0038, 0.9995, 0.9957, 0.9950, 1.0011, 1.0014,
0.9973, 0.9999, 1.0006, 1.0120, 1.0041, 1.0096, 1.0077, 0.9821, 0.9897,
0.9970, 0.9848, 1.0046, 0.9986, 0.9953, 0.9928, 0.9911, 1.0070, 0.9934,
1.0063, 1.0025, 0.9867, 1.0136, 1.0220, 1.0072, 1.0053, 1.0058, 0.9928,
0.9989, 0.9953, 0.9976, 1.0005, 1.0070, 0.9952, 0.9960, 0.9988, 0.9965,
1.0036, 1.0013, 0.9991, 0.9928, 0.9848, 1.0156, 0.9888, 0.9735, 0.9852,
1.0064, 1.0075, 0.9936, 1.0157, 0.9964, 1.0015, 1.0004, 0.9999, 1.0036,
1.0012, 0.9945, 1.0037, 0.9979, 0.9838, 0.9880, 1.0116, 1.0200, 1.0194,
0.9992, 0.9999, 0.9888, 0.9898, 0.9872, 0.9953, 1.0007, 1.0044, 0.9978,
0.9867,1.0073,1.0041,1.0048,1.0048, 0.9954,1.0056,
1.0090,1.0100,0.9965,1.0060,1.0008,1.0112,0.9984,1.0087,0.9985,1.0014,1.0083,
1.0037,0.9986,1.0043,1.0043,0.9990,1.0033,1.0049,0.9849,1.0026,1.0261,1.0203,0.9953,
0.9884,1.0120,0.9945,1.0032,1.0016,1.0031,1.0019,1.0016,0.9993,1.0037,0.9997,0.9977,1.0009,
1.0064,1.0026,1.0066,1.0020,1.0198,0.9736,0.9966,0.9930,1.0088,1.0036,1.0078,1.0072,
1.0012,1.0027,0.9968,0.9971,0.9969,0.9992,1.0021,0.9847,1.0125,0.9966,0.9927,
1.0105,0.9805,0.9927,0.9782,0.9937,1.0158,1.0032,0.9990,0.9968,1.0003,0.9919,1.0039,
1.0014,0.9996,0.9989,0.9990,0.9928,0.9855,1.0040,0.9954,0.9958,0.9974,1.0093,0.9886,
0.9969,0.9940,0.9989,0.9982,0.9997,0.9922,0.9941,0.9970,1.0017,0.9943,0.9930,0.9952,0.9945,
0.9659,0.9881,0.9847,1.0074,0.9939,0.9969,1.0119,0.9979,0.9974,1.0034,0.9989,1.0021,
0.9893,0.9976,1.0081,1.0012,0.9904,1.0096,1.0052,1.0037,0.9991,1.0073,1.0055,1.0130,
1.0042,1.0055,0.9923,0.9965,0.9953,1.0010,1.0086,0.9900,1.0050,1.0073,1.0017,0.9926,
0.9980,0.9993,0.9965,0.9987,0.9896,0.9833,1.0036,1.0025,0.9982,0.9962,0.9941,0.9904,
1.0061,1.0026,0.9871,1.0031,1.0042,0.9986,0.9848,1.0061,1.0061,0.9882,1.0033,1.0014,
0.9935,0.9885,0.9986,0.9979,1.0016,0.9999,0.9946,1.0033,0.9965,0.9934,0.9986,1.0020,
1.0026,0.9950,1.0035,1.0017,1.0030,0.9906,0.9970,1.0020,0.9969,0.9869,1.0037,0.9979,1.0019,
1.0000,0.9984,0.9985,0.9918,1.0029,1.0025,0.9989,1.0071,1.0110,1.0122,1.0183,0.9722,1.0052,
1.0038,1.0121,0.9916,0.9883,0.9993,1.0011,0.9963,1.0038,0.9918,0.9895,1.0007,0.9969,
0.9994,1.0028,0.9950,1.0053,1.0092,0.9779,0.9940,0.9921,0.9991,1.0036,0.9855,0.9951,1.0091,0.9943,
0.9988,0.9931,0.9891,0.9978,0.9965,0.9936,1.0048,0.9997,0.9882,0.9933,1.0087,0.9844,
1.0047,0.9975,0.9951,0.9946,0.9949,1.0035,0.9900,0.9967,0.9912,0.9883,0.9959,0.9898,
1.0009,0.9983,0.9957,1.0030,0.9900,1.0037,1.0078,0.9970,1.0008,0.9866,1.0003,0.9973,1.0057,
0.9929,0.9918,0.9871,0.9988,1.0040,0.9905,1.0012,0.9739,0.9985,1.0050,0.9901,1.0206])

# Pandas dataframe and plot creation
df = pd.DataFrame({'X': IFE_x, 'Y': IFE_y, 'Ratio': IFE_ratio})
table = df.pivot('Y', 'X', 'Ratio')
ax = sns.heatmap(table)
ax.invert_yaxis()
plt.show()

The output I get is the following image. However, I do not want equally spaced mesh. Is there a way to change the way the mesh is spaced on the plot to create something more similar to the first image in this post? Thank you for your help.

enter image description here

Zephyr
  • 11,891
  • 53
  • 45
  • 80
Kevin
  • 75
  • 3
  • 1
    Seaborn doesn't support this. You can use matplotlib's `plt.pcolor()` or `plt.pcolormesh()` to draw a mesh with uneven cells. – JohanC Aug 11 '22 at 19:33
  • See e.g. [Irregularly spaced heatmap](https://stackoverflow.com/questions/62002518/irregularly-spaced-heatmap) – JohanC Aug 11 '22 at 19:57
  • How are you defining the grid sizes / coordinates of the grid rectangles? The coordinates in your data arent the centerpoints of each grid, and they are not the corners. https://imgur.com/4eYPgPv.png – BERA Aug 12 '22 at 19:20

1 Answers1

2

As suggested by JohanC in the comment to your question, you can use matplotlib.axes.Axes.pcolormesh. In order to do this, as explained in the documentation, you need:

  • an array-like X for x axis
  • an array-like Y for y axis
  • a matrix-like C of mapped values

You can use IFE_x and IFE_y for the first two, respectively, without any manipulation. Insted you need to reshape IFE_ratio as a matrix, with:

IFE_ratio = np.reshape(IFE_ratio, (len(IFE_x), len(IFE_y)))

now you can draw the plot:

fig, ax = plt.subplots()

ax.pcolormesh(IFE_x, IFE_y, IFE_ratio.T)

plt.show()

Note that you need to transpose IFE_ratio with .T method, in order to properly draw this plot.

Complete Code

import matplotlib.pyplot as plt
import numpy as np


IFE_x = np.array([7.11815 ,7.19875 ,7.34769 ,7.496   ,7.7413  ,
7.98354 , 8.22184 , 8.45534 , 8.77249 , 9.076   , 9.32338 ,
9.59487 , 9.84534 , 10.04127, 10.24567, 10.4217 , 10.54814,
10.63518, 10.70466, 10.74704, 10.77731])

IFE_y = np.array([24.90 ,24.40 , 23.40 , 22.40 , 21.00 ,16.00 , 11.00 ,6.00, 1.00,
-1.00 ,-6.00 ,-11.00,-16.00,-21.00,-22.40,-23.40,-24.40,-24.90,-25.40])

IFE_ratio = np.array([1.0155, 0.9938, 0.9872, 0.9959, 1.0112, 0.9983,
1.0054, 0.9910, 1.0042, 0.9994, 1.0028, 1.0016, 1.0127, 1.0094, 1.0115,
0.9852, 0.9989, 0.9896, 0.9968, 1.0156, 0.9999, 0.9950, 1.0074, 0.9979,
0.9967, 1.0036, 0.9962, 1.0046, 0.9960, 1.0015, 1.0040, 1.0120, 1.0099,
1.0138, 1.0059, 1.0341, 0.9593, 1.0268, 0.9871, 0.9954, 0.9994, 1.0217,
0.9832, 1.0012, 1.0040, 1.0038, 0.9995, 0.9957, 0.9950, 1.0011, 1.0014,
0.9973, 0.9999, 1.0006, 1.0120, 1.0041, 1.0096, 1.0077, 0.9821, 0.9897,
0.9970, 0.9848, 1.0046, 0.9986, 0.9953, 0.9928, 0.9911, 1.0070, 0.9934,
1.0063, 1.0025, 0.9867, 1.0136, 1.0220, 1.0072, 1.0053, 1.0058, 0.9928,
0.9989, 0.9953, 0.9976, 1.0005, 1.0070, 0.9952, 0.9960, 0.9988, 0.9965,
1.0036, 1.0013, 0.9991, 0.9928, 0.9848, 1.0156, 0.9888, 0.9735, 0.9852,
1.0064, 1.0075, 0.9936, 1.0157, 0.9964, 1.0015, 1.0004, 0.9999, 1.0036,
1.0012, 0.9945, 1.0037, 0.9979, 0.9838, 0.9880, 1.0116, 1.0200, 1.0194,
0.9992, 0.9999, 0.9888, 0.9898, 0.9872, 0.9953, 1.0007, 1.0044, 0.9978,
0.9867,1.0073,1.0041,1.0048,1.0048, 0.9954,1.0056,
1.0090,1.0100,0.9965,1.0060,1.0008,1.0112,0.9984,1.0087,0.9985,1.0014,1.0083,
1.0037,0.9986,1.0043,1.0043,0.9990,1.0033,1.0049,0.9849,1.0026,1.0261,1.0203,0.9953,
0.9884,1.0120,0.9945,1.0032,1.0016,1.0031,1.0019,1.0016,0.9993,1.0037,0.9997,0.9977,1.0009,
1.0064,1.0026,1.0066,1.0020,1.0198,0.9736,0.9966,0.9930,1.0088,1.0036,1.0078,1.0072,
1.0012,1.0027,0.9968,0.9971,0.9969,0.9992,1.0021,0.9847,1.0125,0.9966,0.9927,
1.0105,0.9805,0.9927,0.9782,0.9937,1.0158,1.0032,0.9990,0.9968,1.0003,0.9919,1.0039,
1.0014,0.9996,0.9989,0.9990,0.9928,0.9855,1.0040,0.9954,0.9958,0.9974,1.0093,0.9886,
0.9969,0.9940,0.9989,0.9982,0.9997,0.9922,0.9941,0.9970,1.0017,0.9943,0.9930,0.9952,0.9945,
0.9659,0.9881,0.9847,1.0074,0.9939,0.9969,1.0119,0.9979,0.9974,1.0034,0.9989,1.0021,
0.9893,0.9976,1.0081,1.0012,0.9904,1.0096,1.0052,1.0037,0.9991,1.0073,1.0055,1.0130,
1.0042,1.0055,0.9923,0.9965,0.9953,1.0010,1.0086,0.9900,1.0050,1.0073,1.0017,0.9926,
0.9980,0.9993,0.9965,0.9987,0.9896,0.9833,1.0036,1.0025,0.9982,0.9962,0.9941,0.9904,
1.0061,1.0026,0.9871,1.0031,1.0042,0.9986,0.9848,1.0061,1.0061,0.9882,1.0033,1.0014,
0.9935,0.9885,0.9986,0.9979,1.0016,0.9999,0.9946,1.0033,0.9965,0.9934,0.9986,1.0020,
1.0026,0.9950,1.0035,1.0017,1.0030,0.9906,0.9970,1.0020,0.9969,0.9869,1.0037,0.9979,1.0019,
1.0000,0.9984,0.9985,0.9918,1.0029,1.0025,0.9989,1.0071,1.0110,1.0122,1.0183,0.9722,1.0052,
1.0038,1.0121,0.9916,0.9883,0.9993,1.0011,0.9963,1.0038,0.9918,0.9895,1.0007,0.9969,
0.9994,1.0028,0.9950,1.0053,1.0092,0.9779,0.9940,0.9921,0.9991,1.0036,0.9855,0.9951,1.0091,0.9943,
0.9988,0.9931,0.9891,0.9978,0.9965,0.9936,1.0048,0.9997,0.9882,0.9933,1.0087,0.9844,
1.0047,0.9975,0.9951,0.9946,0.9949,1.0035,0.9900,0.9967,0.9912,0.9883,0.9959,0.9898,
1.0009,0.9983,0.9957,1.0030,0.9900,1.0037,1.0078,0.9970,1.0008,0.9866,1.0003,0.9973,1.0057,
0.9929,0.9918,0.9871,0.9988,1.0040,0.9905,1.0012,0.9739,0.9985,1.0050,0.9901,1.0206])

IFE_ratio = np.reshape(IFE_ratio, (len(IFE_x), len(IFE_y)))


fig, ax = plt.subplots()

ax.pcolormesh(IFE_x, IFE_y, IFE_ratio.T)

plt.show()

Plot

enter image description here

Zephyr
  • 11,891
  • 53
  • 45
  • 80