matplotlib-控制行样式/大量行的capstyle [英] matplotlib - control capstyle of line collection/large number of lines

查看:134
本文介绍了matplotlib-控制行样式/大量行的capstyle的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

类似于我的先前的问题,我想控制使用matplotlib绘制的线的capstyle.但是,我的线条非常多,用线条集合以外的任何其他东西绘制的时间都太长了.是否有任何变通方法来以通用方式(或以超快速方式绘制大量Line2D线)来控制线集合中线的样式.例如,我尝试通过以下方式使用matplotlib rc设置:

Similarly to a previous question of mine, I'd like to control the capstyle of lines being drawn using matplotlib. However, I have an extremely large number of lines, and drawing with anything other than a line collection takes way too long. Are there any workarounds to control the capstyle of lines in a line collection in a generic way (or alternatively, super fast ways of drawing a large number of Line2D lines). For instance, I've tried using the matplotlib rc settings via:

import matplotlib as mpl
mpl.rcParams['lines.solid_capstyle'] = 'round'
mpl.rcParams['lines.solid_joinstyle'] = 'round'

但这似乎没有任何影响.从collections.py的文档字符串:

But this doesn't appear to have any affect. From the docstring for collections.py:

这些类并不像它们的单个元素对应类那样灵活(例如,您可能无法选择所有线条样式),但是它们对于普通用例(例如,大量的实线课程)来说是快速的)

The classes are not meant to be as flexible as their single element counterparts (e.g. you may not be able to select all line styles) but they are meant to be fast for common use cases (e.g. a large set of solid line segemnts)

哪个解释了为什么我似乎无法控制各种参数,但是我仍然想这样做!我看过AGG后端的代码(_backend_agg.cpp:不是我真正理解它),看来line_cap和line_join由gc.capgc.join控制,其中gc来自GCAgg类.有谁知道如何从Python控制它?我在这里问正确的问题吗?也许那是控制这些参数的简便方法?

Which explains why I can't seem to control various parameters, but I still want to do it! I've had a look at the code for the AGG backend (_backend_agg.cpp: not that I really understand it), and it appears that line_cap and line_join are controlled by gc.cap and gc.join, where gc comes from the GCAgg class. Does anyone know how one can control this from Python? Am I asking the right question here? Perhaps that are easier ways to control these parameters?

我们非常感谢您的帮助...我迫切希望能够正常工作,因此甚至欢迎疯狂的黑客入侵!

Any help is greatly appreciated... I'm desperate to get this working, so even crazy hacks are welcome!

谢谢

卡森

推荐答案

由于您在问题中提到您不介意肮脏"的解决方案,因此一种选择如下.

Since you mention in your question that you don't mind "dirty" solutions, one option would as follows.

特定的LineCollection的绘制过程"由Collection类(LineCollection的基础)中定义的draw方法处理.此方法通过语句gc = renderer.new_gc()创建GraphicsContextBase的实例(在backend_bases.py中定义).似乎正是这个对象控制着其他控制capstyle(属性_capstyle)的属性.因此,可以将GraphicsContextBase子类化,重写_capstyle属性,然后将新的new_gc方法注入到RendererBase类中,以便随后对new_gc的调用返回定制的实例:

The "drawing process" of a particular LineCollection is handled by the draw method defined in the Collection class (the base of LineCollection). This method creates an instance of GraphicsContextBase (defined in backend_bases.py) via the statement gc = renderer.new_gc(). It seems to be exactly this object which governs among other things the properties controlling the capstyle (property _capstyle). Therefore, one could subclass GraphicsContextBase, override the _capstyle property, and inject a new new_gc method into the RendererBase class so that consequent calls to new_gc return the customized instance:

从@florisvb的答案中借用示例(假设使用Python3):

Borrowing the example from the answer by @florisvb (assuming Python3):

#!/usr/bin/env python
import types

import numpy as np
from matplotlib.backend_bases import GraphicsContextBase, RendererBase
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection

class GC(GraphicsContextBase):
    def __init__(self):
        super().__init__()
        self._capstyle = 'round'

def custom_new_gc(self):
    return GC()

RendererBase.new_gc = types.MethodType(custom_new_gc, RendererBase)
#----------------------------------------------------------------------
np.random.seed(42)

x = np.random.random(10)
y = np.random.random(10)

points = np.array([x, y]).T.reshape((-1, 1, 2))
segments = np.concatenate([points[:-1], points[1:]], axis=1)

fig = plt.figure()
ax = fig.add_subplot(111)

linewidth = 10
lc = LineCollection(segments, linewidths=linewidth)
ax.add_collection(lc)

fig.savefig('fig.png')

这将产生:

这篇关于matplotlib-控制行样式/大量行的capstyle的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆