我有一个带有交互式图形的程序,偶尔会绘制许多艺术家。在此图中,您还可以使用鼠标进行缩放和平移。但是,缩放平移时的性能不是很好,因为每个艺术家总是要重新绘制。有没有办法检查当前显示区域中有哪些艺术家并只重绘那些艺术家?(在下面的例子中,性能还是比较好的,但可以通过使用更多或更复杂的艺术家来任意变差)
我有一个类似的性能问题hover
,无论何时调用它,它都会canvas.draw()
在最后运行。但是正如您所看到的,我通过使用缓存和恢复轴的背景(基于此)找到了一个巧妙的解决方法。这显着提高了性能,现在即使与许多艺术家一起运行也非常流畅。也许有一种类似的方法可以做到这一点,但对于pan
andzoom
方法?
对于长代码示例很抱歉,其中大部分与问题没有直接关系,但对于突出问题的工作示例来说是必要的。
编辑
我将 MWE 更新为更能代表我的实际代码的内容。
import numpy as np
import sys
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import \
FigureCanvasQTAgg
import matplotlib.patheffects as PathEffects
from matplotlib.text import Annotation
from matplotlib.collections import LineCollection
from PyQt5.QtWidgets import QApplication, QVBoxLayout, QDialog
def check_limits(base_xlim, base_ylim, new_xlim, new_ylim):
if new_xlim[0] < base_xlim[0]:
overlap = base_xlim[0] - new_xlim[0]
new_xlim[0] = base_xlim[0]
if new_xlim[1] + overlap > base_xlim[1]:
new_xlim[1] = base_xlim[1]
else:
new_xlim[1] += overlap …
Run Code Online (Sandbox Code Playgroud) 一年多前,我报告了在腌制一些相当复杂的数据时遇到的一个错误。当时我不知道问题是什么,并认为它可能与递归引用有关。
我在处理项目时多次遇到这个问题,但只做了任意的事情来尝试修复它,直到错误消失。现在我终于花时间找出问题的根源并完善我的 MWE。这就是我想出的:
import pickle
import numpy as np
# create data
dtypes = [('f0', 'O')]
# for some reason, I need at least an extra of 19 fields for it to crash
# immediately
dtypes += [(f'f{i+1}', 'i4') for i in range(19)]
data = np.empty(1, dtype=dtypes)
# print(data[0])
# dump data
dump = pickle.dumps(data[0], pickle.HIGHEST_PROTOCOL)
# print('dumping works')
# load data
load = pickle.loads(dump)
# print('loading works')
# process crashes here if len(dtypes) > 19
print(load)
# …
Run Code Online (Sandbox Code Playgroud) 我知道标题可能有点混乱,所以让我举个例子。假设您有一个基类Base
,它旨在被子类化以创建更复杂的对象。但是您还有一些可选功能,您不需要每个子类都需要这些功能,因此您将它放在一个二级类中OptionalStuffA
,该二级类始终打算与基类一起进行子类化。你也应该让那个次要类成为 的子类Base
吗?
这当然是唯一相关,如果你有一个以上的OptionalStuff
班,你想给他们以不同的方式结合起来,否则你不需要子类均Base
和OptionalStuffA
(,只是有OptionalStuffA
成为的一个子类Base
,所以你只需要在子类OptionalStuffA
)。我Base
知道如果从Base
.
下面是一个示例场景。我还将QObject
该类作为“第三方”令牌类放入该类,其功能对于其中一个辅助类工作是必需的。我在哪里子类化它?下面的例子显示了我到目前为止是如何做到的,但我怀疑这是要走的路。
from PyQt5.QtCore import QObject
class Base:
def __init__(self):
self._basic_stuff = None
def reset(self):
self._basic_stuff = None
class OptionalStuffA:
def __init__(self):
super().__init__()
self._optional_stuff_a = None
def reset(self):
if hasattr(super(), 'reset'):
super().reset()
self._optional_stuff_a = None
def do_stuff_that_only_works_if_my_children_also_inherited_from_Base(self):
self._basic_stuff = not None
class OptionalStuffB:
def __init__(self):
super().__init__()
self._optional_stuff_b = None
def reset(self):
if hasattr(super(), 'reset'): …
Run Code Online (Sandbox Code Playgroud) 如果您提供(整数)幂作为输入,那么创建相应的 10 次幂的最快方法是什么?我可以提出以下四种替代方案,最快的方法似乎是使用 f 字符串:
from functools import partial
from time import time
import numpy as np
def fstring(power):
return float(f'1e{power}')
def asterisk(power):
return 10**power
methods = {
'fstring': fstring,
'asterisk': asterisk,
'pow': partial(pow, 10),
'np.pow': partial(np.power, 10, dtype=float)
}
# "dtype=float" is necessary because otherwise it will raise:
# ValueError: Integers to negative integer powers are not allowed.
# see https://stackoverflow.com/a/43287598/5472354
powers = [int(i) for i in np.arange(-10000, 10000)]
for name, method in methods.items():
start = time()
for i …
Run Code Online (Sandbox Code Playgroud) 在这篇文章之后,我尝试通过创建类来创建 logit 正态分布LogitNormal
:
import numpy as np
import matplotlib.pyplot as plt
from scipy.special import logit
from scipy.stats import norm, rv_continuous
class LogitNormal(rv_continuous):
def _pdf(self, x, **kwargs):
return norm.pdf(logit(x), **kwargs)/(x*(1-x))
class OtherLogitNormal:
def pdf(self, x, **kwargs):
return norm.pdf(logit(x), **kwargs)/(x*(1-x))
fig, ax = plt.subplots()
values = np.linspace(10e-10, 1-10e-10, 1000)
sigma, mu = 1.78, 0
ax.plot(
values, LogitNormal().pdf(values, loc=mu, scale=sigma), label='subclassed'
)
ax.plot(
values, OtherLogitNormal().pdf(values, loc=mu, scale=sigma),
label='not subclassed'
)
ax.legend()
fig.show()
Run Code Online (Sandbox Code Playgroud)
然而,该LogitNormal
课程并没有产生预期的结果。当我不子类化时rv_continuous
它会起作用。这是为什么?我需要子类化才能工作,因为我还需要它附带的其他方法,例如rvs
.
顺便说一句,我在 …
我正在尝试将数据点从数据坐标系转换为 matplotlib 中的轴坐标系。
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
# this is in data coordinates
point = (1000, 1000)
# this takes us from the data coordinates to the display coordinates.
trans = ax.transData.transform(point)
print(trans) # so far so good.
# this should take us from the display coordinates to the axes coordinates.
trans = ax.transAxes.inverted().transform(trans)
# the same but in one line
# trans = (ax.transData + ax.transAxes.inverted()).transform(point)
print(trans) # why did it transform back to the …
Run Code Online (Sandbox Code Playgroud) 我正在尝试实现一种功能,您可以通过单击按钮来隐藏或显示图形。但是,当图形再次隐藏时,对话框窗口的大小不会变回原来的大小。该self.resize()
声明似乎被忽略了。我怎样才能做到这一点?然而,使用setFixedSize()
作品时,我不希望尺寸被固定。我以为我可以使用某种方式“修复”它,setSizePolicy()
但这没有帮助。
import sys
import matplotlib.pyplot as plt
from PyQt5.Qt import QSizePolicy
from PyQt5.QtWidgets import (
QDialog, QApplication, QGridLayout, QWidget, QGroupBox, QPushButton
)
from matplotlib.backends.backend_qt5agg import \
FigureCanvasQTAgg as FigureCanvas
class MainWindow(QDialog):
def __init__(self):
super().__init__()
self.layout = QGridLayout()
self.setLayout(self.layout)
self.settings = QGroupBox('Settings:')
self.settingsLayout = QGridLayout()
self.settings.setLayout(self.settingsLayout)
self.showFigureBtn = QPushButton('Show Figure')
self.settingsLayout.addWidget(self.showFigureBtn)
self.layout.addWidget(self.settings)
self.figureWidget = QWidget()
self.figureWidget.setMinimumSize(300, 300)
self.figureLayout = QGridLayout(self.figureWidget)
self.fig, self.ax = plt.subplots()
self.canvas = FigureCanvas(self.fig)
self.figureLayout.addWidget(self.canvas)
self.figureWidget.setLayout(self.figureLayout)
self.layout.addWidget(self.figureWidget)
self.figureWidget.setVisible(False)
self.showFigureBtn.clicked.connect(self.toggle_figure)
self.min_size = (300, …
Run Code Online (Sandbox Code Playgroud) 我最近询问了创建 10 的幂的最快方法,结果发现最快的方法实际上是一种偷偷摸摸的解决方法,您首先创建所有可能的值,然后在需要时简单地查找它们。
在解决方案中,alist
被用作查找表,但是,我刚刚了解到,在查找操作方面dicts
应该要快得多(另请参见此处)。但是当我尝试使用 adict
作为查找表时,过程实际上更慢:
n = 200
18 ns 18 ns 18 ns f[n] # list
22 ns 22 ns 22 ns g[n] # dict
n = -200
18 ns 18 ns 18 ns f[n] # list
29 ns 29 ns 29 ns g[n] # dict
Run Code Online (Sandbox Code Playgroud)
这是为什么?这是否与它们是keys
整数而不是字符串有关?(而且我猜sets
在这种情况下不能使用?)
这是我运行的代码:
from timeit import repeat
solutions = [
'f[n] # list',
'g[n] # dict', …
Run Code Online (Sandbox Code Playgroud) python ×8
matplotlib ×2
dictionary ×1
distribution ×1
list ×1
lookup ×1
numpy ×1
performance ×1
pickle ×1
pycharm ×1
pyqt ×1
pyqt5 ×1
resize ×1
scipy ×1
statistics ×1
transform ×1