回答此问题可获得 20 贡献值,回答如果被采纳可获得 50 分。
<p>我目前正在完成一个更大的项目,最后一部分是添加一个简单的图例到一个多色线的情节。这行只包含两种不同的颜色。在</p>
<p>下图显示了创建时的绘图。<a href="https://i.stack.imgur.com/f4tRz.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/f4tRz.png" alt="https://drive.google.com/open?id=1VYehsd6ByqdpZcS0u7Uh7OjklNqMgs_H"/></a></p>
<p>下一张图片显示了同样的图,分辨率更高。<a href="https://i.stack.imgur.com/V1Rqq.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/V1Rqq.png" alt="enter image description here"/></a></p>
<p>图中显示了地球和火星之间的距离。三月到八月,这条线是橙色的,其他月份是蓝色的。图例应该出现在绘图右上角的一个简单的框中,为使用的颜色分别显示一个标签。像<a href="https://matplotlib.org/_images/sphx_glr_usage_003.png" rel="nofollow noreferrer">this</a>这样的东西会很好。在</p>
<p>图中的数据来自一个我命名为<code>master_array</code>的巨大矩阵。在展示这个问题所涉及的情节之前,它包含了很多对于一些任务来说是必要的信息。
对于我正在挣扎的绘图来说,重要的是第0、1和6列,它们包含日期、相关日期的行星之间的距离,在第6列中,我设置了一个标志,以确定给定的点是否属于“三月至八月”集合(<code>0</code>表示九月-二月/“冬季”,<code>1</code>表示三月-八月/“夏季”)。<code>master_array</code>是一个numpy数组,dtype是<code>float64</code>。它包含大约45k个数据点。在</p>
<p>它看起来像:</p>
<pre class="lang-py prettyprint-override"><code>In [3]: master_array
Out[3]:
array([[ 1.89301010e+07, 1.23451036e+00, -8.10000000e+00, ...,
1.00000000e+00, 1.00000000e+00, 1.89300000e+03],
[ 1.89301020e+07, 1.24314818e+00, -8.50000000e+00, ...,
2.00000000e+00, 1.00000000e+00, 1.89300000e+03],
[ 1.89301030e+07, 1.25179997e+00, -9.70000000e+00, ...,
3.00000000e+00, 1.00000000e+00, 1.89300000e+03],
...,
[ 2.01903100e+07, 1.84236878e+00, 7.90000000e+00, ...,
1.00000000e+01, 3.00000000e+00, 2.01900000e+03],
[ 2.01903110e+07, 1.85066892e+00, 5.50000000e+00, ...,
1.10000000e+01, 3.00000000e+00, 2.01900000e+03],
[ 2.01903120e+07, 1.85894904e+00, 9.40000000e+00, ...,
1.20000000e+01, 3.00000000e+00, 2.01900000e+03]])
</code></pre>
<p>这是获取我在开头描述的绘图的函数:</p>
^{pr2}$
<p>在更大的脚本中还有另一个函数(散点图)来标记曲线的最小值和最大值,但我想这在这里并不重要。在</p>
<p>我已经尝试了<a href="https://stackoverflow.com/questions/49223702/adding-a-legend-to-a-matplotlib-plot-with-a-multicolored-line">this</a>生成了一个图例,它显示了一个垂直的颜色条和一个标签,以及<a href="https://stackoverflow.com/questions/19877666/add-legends-to-linecollection-plot">this question</a>答案中描述的两个选项,因为它看起来更像我的目标,但无法使其适用于我的案例。在</p>
<p>也许我应该补充一下,我只是python的初学者,这是我的第一个项目,所以我不熟悉<code>matplotlib</code>更深层的功能,这可能是为什么我不能定制上述答案,使其在我的情况下工作的原因。在</p>
<hr/>
<p><strong>更新</strong></p>
<p>感谢用户ImportanceOfBeingErnest的帮助,我做了一些改进:
<a href="https://i.stack.imgur.com/4alev.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/4alev.png" alt=""improvements""/></a></p>
<pre class="lang-py prettyprint-override"><code>import matplotlib.dates as mdates
from matplotlib.collections import LineCollection
from matplotlib.colors import ListedColormap
from matplotlib.lines import Line2D
def md_plot4(dt64=np.array, md=np.array, swFilter=np.array):
y, m, d = dt64.astype(int) // np.c_[[10000, 100, 1]] % np.c_[[10000, 100, 100]]
dt64 = y.astype('U4').astype('M8') + (m-1).astype('m8[M]') + (d-1).astype('m8[D]')
z = np.unique(swFilter)
cmap = ListedColormap(['b','darkorange'])
fig = plt.figure('Test')
plt.title("Test", loc='left', wrap=True)
plt.xlabel("Zeit in Jahren\n")
plt.xticks(rotation = 45)
plt.ylabel("Marsdistanz in AE\n(1 AE = 149.597.870,7 km)")
# plt.legend(loc='upper right', frameon=True) # worked formerly
ax=plt.gca()
plt.style.use('seaborn-whitegrid')
#plt.style.use('classic')
#convert dates to numbers first
inxval = mdates.date2num(dt64)
points = np.array([inxval, md]).T.reshape(-1,1,2)
segments = np.concatenate([points[:-1],points[1:]], axis=1)
lc = LineCollection(segments, array=z, cmap=plt.cm.get_cmap(cmap),
linewidth=3)
# set color to s/w values
lc.set_array(swFilter)
ax.add_collection(lc)
fig.colorbar(lc)
loc = mdates.AutoDateLocator()
ax.xaxis.set_major_locator(loc)
ax.xaxis.set_major_formatter(mdates.AutoDateFormatter(loc))
ax.autoscale_view()
def make_proxy(zvalue, scalar_mappable, **kwargs):
color = scalar_mappable.cmap(scalar_mappable.norm(zvalue))
return Line2D([0, 1], [0, 1], color=color, **kwargs)
proxies = [make_proxy(item, lc, linewidth=2) for item in z]
ax.legend(proxies, ['Winter', 'Summer'])
plt.show()
md_plot4(dt64, md, swFilter)
</code></pre>
<p>+优点:</p>
<p>它显示了一个图例,并且根据标签显示了正确的颜色。在</p>
<p>-还有什么需要优化:</p>
<p>1)图例不在方框中,图例的“线”干扰了绘图的底层。正如用户ImportanceOfBeingErnest指出的,这是由于使用<code>plt.style.use('seaborn-whitegrid')</code>造成的。因此,如果有一种方法可以将<code>plt.style.use('seaborn-whitegrid')</code>与{<cd9>}的图例样式一起使用,这可能会有所帮助。
2) 更大的问题是colorbar。我将<code>fig.colorbar(lc)</code>行添加到原始代码中,以实现我根据<a href="https://stackoverflow.com/questions/19877666/add-legends-to-linecollection-plot/19881647#19881647">this answer</a>查找的内容。在</p>
<p>所以我尝试了一些其他的改变:</p>
<p>我使用了<code>plt.style.use('classic')</code>以我需要的方式获得了一个图例,但这使我失去了前面提到的<code>plt.style.use('seaborn-whitegrid')</code>的漂亮样式。此外,我根据前面提到的<a href="https://stackoverflow.com/questions/19877666/add-legends-to-linecollection-plot/19881647#19881647">answer</a>禁用了前面添加的<code>colorbar</code>行。在</p>
<p>我得到的是:</p>
<p><a href="https://i.stack.imgur.com/Umbtr.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Umbtr.png" alt="more "improvement""/></a></p>
<pre class="lang-py prettyprint-override"><code>import matplotlib.dates as mdates
from matplotlib.collections import LineCollection
from matplotlib.colors import ListedColormap
from matplotlib.lines import Line2D
def md_plot4(dt64=np.array, md=np.array, swFilter=np.array):
y, m, d = dt64.astype(int) // np.c_[[10000, 100, 1]] % np.c_[[10000, 100, 100]]
dt64 = y.astype('U4').astype('M8') + (m-1).astype('m8[M]') + (d-1).astype('m8[D]')
z = np.unique(swFilter)
cmap = ListedColormap(['b','darkorange'])
#fig =
plt.figure('Test')
plt.title("Test", loc='left', wrap=True)
plt.xlabel("Zeit in Jahren\n")
plt.xticks(rotation = 45)
plt.ylabel("Marsdistanz in AE\n(1 AE = 149.597.870,7 km)")
# plt.legend(loc='upper right', frameon=True) # worked formerly
ax=plt.gca()
#plt.style.use('seaborn-whitegrid')
plt.style.use('classic')
#convert dates to numbers first
inxval = mdates.date2num(dt64)
points = np.array([inxval, md]).T.reshape(-1,1,2)
segments = np.concatenate([points[:-1],points[1:]], axis=1)
lc = LineCollection(segments, array=z, cmap=plt.cm.get_cmap(cmap),
linewidth=3)
# set color to s/w values
lc.set_array(swFilter)
ax.add_collection(lc)
#fig.colorbar(lc)
loc = mdates.AutoDateLocator()
ax.xaxis.set_major_locator(loc)
ax.xaxis.set_major_formatter(mdates.AutoDateFormatter(loc))
ax.autoscale_view()
def make_proxy(zvalue, scalar_mappable, **kwargs):
color = scalar_mappable.cmap(scalar_mappable.norm(zvalue))
return Line2D([0, 1], [0, 1], color=color, **kwargs)
proxies = [make_proxy(item, lc, linewidth=2) for item in z]
ax.legend(proxies, ['Winter', 'Summer'])
plt.show()
md_plot4(dt64, md, swFilter)
</code></pre>
<p>+优点:</p>
<p>它以我需要的方式展示了传奇。在</p>
<p>它不再显示颜色条了。在</p>
<p>-什么是优化:</p>
<p>情节不再是五彩缤纷了。在</p>
<p>传说也不是。在</p>
<p><code>classic</code>样式不是我之前解释过的那样。。。在</p>
<hr/>
<p>所以如果有人有好的建议,请告诉我!在</p>
<p>我使用的是numpy版本1.16.2和matplotlib版本3.0.3</p>