gpt4 book ai didi

python - 在 MATPLOTLIB 中绘制多个子图时条形图损坏

转载 作者:太空宇宙 更新时间:2023-11-04 06:33:50 25 4
gpt4 key购买 nike

我创建了一个类,允许用户将多个图表添加到 MATPLOTLIB 窗口。这些可以是折线图或条形图。它还具有以下功能:当图表已添加到窗口(从 rowID 标识)而不是绘制新图时,它将替换旧图中的数据。即它允许更新(动画)

这对于折线图非常有效,但在绘制多个条形图时我会出错。该类看起来像:

  import math

class TFrmPlot():

def __init__(self, point_lists, deleteCallback, plotType, rowID):
import matplotlib
matplotlib.interactive( True )
matplotlib.use( 'WXAgg' )

import matplotlib.pyplot as plt
self.plt = plt
self.fig = plt.figure()
self.fig.canvas.mpl_connect('close_event', self.on_close)

import matplotlib.axes as ax
self.ax = ax

self.deleteCallback = deleteCallback
self.chartArray = []
self.addChart(point_lists, plotType, rowID)

def close(self):
self.plt.close('all')
#self.fig.close()

def replaceChartDataIfChartExists(self, point_lists, rowID):
if rowID==0:
pass
for chart in self.chartArray:
for plot in chart.plots:
if plot.rowID == rowID:
plot.points = point_lists
if plot.plotType=="Point":
plot.plotItem.set_data(point_lists[0],point_lists[1])
chart.subPlot.draw_artist(plot.plotItem)
self.fig.canvas.blit(chart.subPlot.bbox)
else:
for rect, h in zip(plot.plotItem, point_lists[1]):
rect.set_height(h)
chart.subPlot.relim()
chart.subPlot.autoscale_view(True,True,True)
self.plt.draw()
return True
return False

def addChart(self, point_lists, plotType, rowID):
self.chartArray.append(TChart(rowID,plotType,point_lists))
self._drawAll()

def addPlot(self, point_lists, plotType, rowID):
chartNum = len(self.chartArray)
self.chartArray[chartNum-1].plots.append(TPlot(rowID,plotType,point_lists))
self._drawAll()

def on_close(self, event):
self.deleteCallback()

def _drawAll(self):
self.plt.clf()
numSubPlots = len(self.chartArray)
numCols = self._noCols(numSubPlots)
IndexConverter = TIndexConverter(numCols)
subPlot = None
for chartIndex in range(0,numSubPlots):
if numSubPlots==1:
subPlot = self.fig.add_subplot(1,1,1)
elif numSubPlots==2:
subPlot = self.fig.add_subplot(1,2,chartIndex+1)
else:
subPlot = self.fig.add_subplot(2,numCols,IndexConverter._getSubPlotIndex(chartIndex))
subPlot.relim()
subPlot.autoscale_view(True,True,True)
self.chartArray[chartIndex].subPlot = subPlot
self._drawSubs(self.chartArray[chartIndex])
self.plt.show()

def _drawSubs(self, chart):
for plot in chart.plots:
if plot.plotType=="Point":
chart.subPlot.plot(plot.points[0],plot.points[1])
plot.plotItem = chart.subPlot.lines[len(chart.subPlot.lines)-1]
else:
kwargs = {"alpha":0.5}
plot.plotItem = chart.subPlot.bar(plot.points[0],plot.points[1], width=self._calculateleastDiff(plot.points[0]), **kwargs)

def _noCols(self, numSubPlots):
return math.ceil(float(numSubPlots)/2.0)

def _calculateleastDiff(self, xValues):
xValues2 = sorted(xValues)
leastDiff = None
lastValue = None
for value in xValues2:
if lastValue is not None:
diff = value-lastValue
if leastDiff is None or diff < leastDiff:
leastDiff = diff
lastValue = value
return leastDiff

总结起来有点长:

addChart——基本上是添加一个新的子图

addPlot -- 向现有的子图添加新的线或条

replaceChartDataIfChartExists -- 如果 ID 已经存在则刷新数据

我使用的虚拟数据只是连续绘制正梯度和负梯度线。然而,我的地 block 可能会进入一个/一些或所有条形图被破坏的状态。它看起来几乎像 x/y 轴已经旋转,各个条形图不是从 x 轴开始的。问题是间歇性的;有时我会按预期获得几个情节。一旦情节被破坏,所有 future 的更新都会被破坏。

Corrupted Data Plot

按要求,剩余代码:

class TIndexConverter():    
def __init__(self, numCols):
self.evenCounter = 0
self.oddCounter = numCols

def _getSubPlotIndex(self, arrayIndex):
if arrayIndex%2==0:
self.evenCounter += 1
return self.evenCounter
else:
self.oddCounter += 1
return self.oddCounter


class TChart():
def __init__(self, rowID, plotType, point_lists):
self.subPlot = None
self.plots = [TPlot(rowID, plotType, point_lists)]

class TPlot():
def __init__(self, rowID, plotType, point_lists):
self.plotItem = None
self.plotType = plotType
self.rowID = rowID
self.points = point_lists

一些客户端代码:

def _updateData(self, state, data): 
if self.plot is not None:
if not self.plot.replaceChartDataIfChartExists(data, state.comm.rowID):
if self.createNewChart == True:
self.plot.addChart(data, state.setting.plotType, state.comm.rowID)
else:
self.plot.addPlot(data, state.setting.plotType, state.comm.rowID)

最佳答案

这可能相关也可能不相关,但您可以将 _calculateleastDiff 替换为以下内容。

def _calculateleastDiff(self, xValues):
return np.min(np.diff(sorted(xValues)))

这段代码的功能方式过于复杂。我怀疑您可以去掉 TChartTPlot 类。我会保留一个数据列表列表(所以 [ [subplot1_data1,subplot1_data2],[subplot2_data1],[...]])一个 axes 对象列表,以及一个列表,用于跟踪您想要的情节类型。

此外,尽量不要使用 matplotlib 中已经使用的名称,这会使您的代码更难阅读。

关于python - 在 MATPLOTLIB 中绘制多个子图时条形图损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13879263/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com