S.J*_*rwe 13 python matplotlib
是否有人知道是否可以在图中旋转图例matplotlib?我使用下面的代码制作了一个简单的图,并在绘画中编辑了图表以显示我想要的内容.
plt.plot([4,5,6], label = 'test')
ax = plt.gca()
ax.legend()
plt.show()
Run Code Online (Sandbox Code Playgroud)
legendAsLatex我遇到了类似的问题,并通过编写生成用作 y 轴标签的乳胶代码的函数来解决它。该函数收集提供给绘图函数的颜色、标记、线条样式和标签。它需要启用乳胶并加载所需的包。下面是生成带有使用两个垂直轴的额外曲线的绘图的代码。
from matplotlib import pyplot as plt
import matplotlib.colors as cor
plt.rc('text', usetex=True)
plt.rc('text.latex', preamble=r'\usepackage{amsmath} \usepackage{wasysym}'+
r'\usepackage[dvipsnames]{xcolor} \usepackage{MnSymbol} \usepackage{txfonts}')
def legendAsLatex(axes, rotation=90) :
'''Generate a latex code to be used instead of the legend.
Uses the label, color, marker and linestyle provided to the pyplot.plot.
The marker and the linestyle must be defined using the one or two character
abreviations shown in the help of pyplot.plot.
Rotation of the markers must be multiple of 90.
'''
latexLine = {'-':'\\textbf{\Large ---}',
'-.':'\\textbf{\Large --\:\!$\\boldsymbol{\cdot}$\:\!--}',
'--':'\\textbf{\Large --\,--}',':':'\\textbf{\Large -\:\!-}'}
latexSymbol = {'o':'medbullet', 'd':'diamond', 's':'filledmedsquare',
'D':'Diamondblack', '*':'bigstar', '+':'boldsymbol{\plus}',
'x':'boldsymbol{\\times}', 'p':'pentagon', 'h':'hexagon',
',':'boldsymbol{\cdot}', '_':'boldsymbol{\minus}','<':'LHD',
'>':'RHD','v':'blacktriangledown', '^':'blacktriangle'}
rot90=['^','<','v','>']
di = [0,-1,2,1][rotation%360//90]
latexSymbol.update({rot90[i]:latexSymbol[rot90[(i+di)%4]] for i in range(4)})
return ', '.join(['\\textcolor[rgb]{'\
+ ','.join([str(x) for x in cor.to_rgb(handle.get_color())]) +'}{'
+ '$\\'+latexSymbol.get(handle.get_marker(),';')+'$'
+ latexLine.get(handle.get_linestyle(),'') + '} ' + label
for handle,label in zip(*axes.get_legend_handles_labels())])
ax = plt.axes()
ax.plot(range(0,10), 'b-', label = 'Blue line')
ax.plot(range(10,0,-1), 'sm', label = 'Magenta squares')
ax.set_ylabel(legendAsLatex(ax))
ax2 = plt.twinx()
ax2.plot([x**0.5 for x in range(0,10)], 'ro', label = 'Red circles')
ax2.plot([x**0.5 for x in range(10,0,-1)],'g--', label = 'Green dashed line')
ax2.set_ylabel(legendAsLatex(ax2))
plt.savefig('legend.eps')
plt.close()
Run Code Online (Sandbox Code Playgroud)
代码生成的图:
昨天我花了几个小时对此进行了研究,并取得了一些进展,因此我将在下面分享这一点以及一些未来的建议。
首先,看起来我们当然可以旋转和平移图例周围的边界框(bbox)或框架。在下面的第一个示例中,您可以看到transform可以应用 a,尽管在应用 90 度旋转后需要一些奇怪的大平移数。但是,将翻译后的图例框架保存到图像文件中实际上存在问题,因此我不得不从 IPython 笔记本中截取屏幕截图。我也添加了一些评论。
import matplotlib.pyplot as plt
%matplotlib inline
import numpy as np
import matplotlib.transforms
fig = plt.figure()
ax = fig.add_subplot('121') #make room for second subplot, where we are actually placing the legend
ax2 = fig.add_subplot('122') #blank subplot to make space for legend
ax2.axis('off')
ax.plot([4,5,6], label = 'test')
transform = matplotlib.transforms.Affine2D(matrix=np.eye(3)) #start with the identity transform, which does nothing
transform.rotate_deg(90) #add the desired 90 degree rotation
transform.translate(410,11) #for some reason we need to play with some pretty extreme translation values to position the rotated legend
legend = ax.legend(bbox_to_anchor=[1.5,1.0])
legend.set_title('test title')
legend.get_frame().set_transform(transform) #This actually works! But, only for the frame of the legend (see below)
frame = legend.get_frame()
fig.subplots_adjust(wspace = 0.4, right = 0.9)
fig.savefig('rotate_legend_1.png',bbox_extra_artists=(legend,frame),bbox_inches='tight', dpi = 300) #even with the extra bbox parameters the legend frame is still getting clipped
Run Code Online (Sandbox Code Playgroud)
接下来,我认为探索get_methods()其他图例组件是明智的。dir(legend)你可以用等等来挖掘这些东西legend.__dict__。特别是,我注意到您可以这样做:legend.get_title().set_transform(transform),这似乎意味着我们可以翻译图例文本(而不仅仅是上面的框架)。让我们看看当我尝试时会发生什么:
fig2 = plt.figure()
ax = fig2.add_subplot('121')
ax2 = fig2.add_subplot('122')
ax2.axis('off')
ax.plot([4,5,6], label = 'test')
transform = matplotlib.transforms.Affine2D(matrix=np.eye(3))
transform.rotate_deg(90)
transform.translate(410,11)
legend = ax.legend(bbox_to_anchor=[1.5,1.0])
legend.set_title('test title')
legend.get_frame().set_transform(transform)
legend.get_title().set_transform(transform) #one would expect this to apply the same transformation to the title text in the legend, rotating it 90 degrees and translating it
frame = legend.get_frame()
fig2.subplots_adjust(wspace = 0.4, right = 0.9)
fig2.savefig('rotate_legend_1.png',bbox_extra_artists=(legend,frame),bbox_inches='tight', dpi = 300)
Run Code Online (Sandbox Code Playgroud)
图例标题似乎在 IPython 笔记本的屏幕截图中消失了。但是,如果我们查看保存的文件,图例标题现在位于左下角,并且似乎忽略了转换的旋转组件(为什么?):
我对这种方法也遇到了类似的技术困难:
bbox = matplotlib.transforms.Bbox([[0.,1],[1,1]])
trans_bbox = matplotlib.transforms.TransformedBbox(bbox, transform)
legend.set_bbox_to_anchor(trans_bbox)
Run Code Online (Sandbox Code Playgroud)
其他注意事项和建议:
| 归档时间: |
|
| 查看次数: |
3994 次 |
| 最近记录: |