如何制作 Pandas DataFrame 的简单等高线图,其中数字单元格值为 Z 并标记为 rows/columns 作为 X 和 Y 坐标?

How do I make a make a simple contour chart of a Pandas DataFrame with numeric cell values as Z and labeled rows/columns as X and Y coordinates?

我有一个 Pandas DataFrame,luminance_df,它看起来像这样:

barelyvisible ultralight light abitlight medium abitdark dark evendarker ultradark almostblack
orange 96 92 83 72 61 53 48 40 34 28
gold 96 89 77 65 56 50 44 37 31 26
yellow 95 88 77 64 53 47 40 33 29 26
chartreuse 95 89 80 67 55 44 35 27 23 20
green 97 93 85 73 58 45 36 29 24 20
forest 96 90 80 67 52 39 30 24 20 16
aqua 97 89 78 64 50 40 32 26 22 19
teal 96 90 82 69 53 43 36 31 27 24
lightblue 97 94 86 74 60 48 39 32 27 24
blue 97 93 87 78 68 60 53 48 40 33
indigo 97 94 89 82 74 67 59 51 41 34
purple 98 95 92 85 76 66 58 50 42 35
royalpurple 98 95 92 85 75 65 56 47 39 32
magenta 98 95 91 83 73 61 49 40 33 28
pink 97 95 90 82 70 60 51 42 35 30
dustypink 97 95 90 82 71 60 50 41 35 30
red 97 94 89 82 71 60 51 42 35 31

到目前为止,我正在构建一个多图表 HTML 文件,如下所示:

with open(os.path.join(cwd, 'testout.html'), 'w') as outfile:
    outfile.write("<p>&nbsp;</p><hr/><p>&nbsp;</p>".join(['<h1>Colors</h1>'+hex_styler.to_html(), '<h1>Hue</h1>'+hue_styler.to_html(), '<h1>Saturation</h1>'+saturation_styler.to_html(
    ), '<h1>Luminance</h1>'+luminance_styler.to_html(), '<h1>Perceived Brightness</h1>'+perceived_brightness_pivot_styler.to_html(), '<h1>Base Data</h1>'+basic_df.to_html()]))

我想在 luminance_styler.to_html() 之后显示一个 elevation/contour 样式的亮度图,很像我在 Excel:

中制作的这张图

我希望颜色保持“从上到下”排序,作为 y 轴上的值,而深色保持“从左到右”排序,作为 x 轴上的值,就像在示例中一样以上。

问题

我不是数据科学家,也不经常使用 Python。我为自己首先制作 luminance_df 感到自豪,但我并没有想出如何简单地制作 Python ...两个方向的标签都是字符串的DataFrame ...作为z轴并制作它的等高线图。

我 Google 所做的一切都会导致非常复杂的数据科学细微问题。

有人可以通过给我基本的“hello world”代码让我走上正轨,让我至少了解 Python 中 luminance_df 的数据我在 Excel?

中使用了“插入图表”按钮

如果你能找到我,那么我就有了一个 image_base64 = base64.b64encode(img.read()).decode("utf-8")-able 的 img = BytesIO(),我可以 f'<img src="data:image/png;base64, {image_base64}" />' 自己将它变成 testout.html 的字符串连接.

我在 Windows 并且我自己设置为能够 pip install

注释

  1. 公平地说,我发现这些等高线图比 Excel 制作的更有吸引力,也更容易阅读,但我可以接受一些“野蛮”的东西-看起来像 Excel 版本,只要它使“上升”和“下降”变得明显,并且只要它使用 ROYIGBV 彩虹来指示“更少”与“更多”(讨厌关于默认 Excel 颜色的我的意见 -- 是的,我知道,这可能是一个可访问性问题):

  2. 虽然我希望图表的颜色遵循某种“彩虹”(因为我个人认为它们易于阅读),但任何“彩虹”图表上的阴影”应该完全忽略 y 轴的标签恰好描述颜色的事实。没有任何相关性。我只是在绘制 16 到 98 之间的数字事实;图表的颜色应该仅表示这两个极端之间“高度”的变化。

到目前为止的努力

到目前为止我发现的唯一一个看起来相似的“简单”问题是 Convert pandas DataFrame to a 3d graph using Index and Columns as X,Y and values as Z?,但这段代码对我来说根本不起作用,所以我什至不知道它输出什么,视觉上,所以我不知道它是否相关:

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
lumX = luminance_df.columns
lumY = luminance_df.index
lumZ = luminance_df.values
fig = plt.figure()
ax = plt.axes(projection = '3d')
ax.contour3D(lumX,lumY,lumZ)

我的脚本出错并显示一条消息:ValueError: could not convert string to float: 'orange',而且我不知道我在做什么以适应这个答案似乎是围绕数字 X 的假设编写的- 和 Y 轴键。 (此外,它可能不会生成我希望的图表类型——正如我所说,无法判断,因为它甚至不执行,而且答案中没有视觉样本。)

数据集

准备 pandas.DataFrame():

{"barelyvisible":{"orange":96,"gold":96,"yellow":95,"chartreuse":95,"green":97,"forest":96,"aqua":97,"teal":96,"lightblue":97,"blue":97,"indigo":97,"purple":98,"royalpurple":98,"magenta":98,"pink":97,"dustypink":97,"red":97},"ultralight":{"orange":92,"gold":89,"yellow":88,"chartreuse":89,"green":93,"forest":90,"aqua":89,"teal":90,"lightblue":94,"blue":93,"indigo":94,"purple":95,"royalpurple":95,"magenta":95,"pink":95,"dustypink":95,"red":94},"light":{"orange":83,"gold":77,"yellow":77,"chartreuse":80,"green":85,"forest":80,"aqua":78,"teal":82,"lightblue":86,"blue":87,"indigo":89,"purple":92,"royalpurple":92,"magenta":91,"pink":90,"dustypink":90,"red":89},"abitlight":{"orange":72,"gold":65,"yellow":64,"chartreuse":67,"green":73,"forest":67,"aqua":64,"teal":69,"lightblue":74,"blue":78,"indigo":82,"purple":85,"royalpurple":85,"magenta":83,"pink":82,"dustypink":82,"red":82},"medium":{"orange":61,"gold":56,"yellow":53,"chartreuse":55,"green":58,"forest":52,"aqua":50,"teal":53,"lightblue":60,"blue":68,"indigo":74,"purple":76,"royalpurple":75,"magenta":73,"pink":70,"dustypink":71,"red":71},"abitdark":{"orange":53,"gold":50,"yellow":47,"chartreuse":44,"green":45,"forest":39,"aqua":40,"teal":43,"lightblue":48,"blue":60,"indigo":67,"purple":66,"royalpurple":65,"magenta":61,"pink":60,"dustypink":60,"red":60},"dark":{"orange":48,"gold":44,"yellow":40,"chartreuse":35,"green":36,"forest":30,"aqua":32,"teal":36,"lightblue":39,"blue":53,"indigo":59,"purple":58,"royalpurple":56,"magenta":49,"pink":51,"dustypink":50,"red":51},"evendarker":{"orange":40,"gold":37,"yellow":33,"chartreuse":27,"green":29,"forest":24,"aqua":26,"teal":31,"lightblue":32,"blue":48,"indigo":51,"purple":50,"royalpurple":47,"magenta":40,"pink":42,"dustypink":41,"red":42},"ultradark":{"orange":34,"gold":31,"yellow":29,"chartreuse":23,"green":24,"forest":20,"aqua":22,"teal":27,"lightblue":27,"blue":40,"indigo":41,"purple":42,"royalpurple":39,"magenta":33,"pink":35,"dustypink":35,"red":35},"almostblack":{"orange":28,"gold":26,"yellow":26,"chartreuse":20,"green":20,"forest":16,"aqua":19,"teal":24,"lightblue":24,"blue":33,"indigo":34,"purple":35,"royalpurple":32,"magenta":28,"pink":30,"dustypink":30,"red":31}}

我相信你只需要做一个countourf:

plt.contourf(df, cmap='RdYlBu')
plt.xticks(range(df.shape[1]), df.columns, rotation=90)
plt.yticks(range(df.shape[0]), df.index)
plt.show()

输出:

或热图:

import seaborn as sns
sns.heatmap(df, cmap='RdYlBu')

输出: