Merge pull request #4150 from alexbruy/processing-graphs

[processing] improve graphs
This commit is contained in:
Alexander Bruy 2017-02-16 14:42:08 +02:00 committed by GitHub
commit f587ae5f30
7 changed files with 70 additions and 110 deletions

View File

@ -25,8 +25,8 @@ __copyright__ = '(C) 2013, Victor Olaya'
__revision__ = '$Format:%H$'
import matplotlib.pyplot as plt
import matplotlib.pylab as lab
import plotly as plt
import plotly.graph_objs as go
import numpy as np
from processing.core.parameters import ParameterTable
@ -69,13 +69,8 @@ class BarPlot(GeoAlgorithm):
output = self.getOutputValue(self.OUTPUT)
values = vector.values(layer, namefieldname, valuefieldname)
plt.close()
ind = np.arange(len(values[namefieldname]))
width = 0.8
plt.bar(ind, values[valuefieldname], width, color='r')
plt.xticks(ind, values[namefieldname], rotation=45)
plotFilename = output + '.png'
lab.savefig(plotFilename)
with open(output, 'w') as f:
f.write('<html><img src="' + plotFilename + '"/></html>')
data = [go.Bar(x=ind,
y=values[valuefieldname])]
plt.offline.plot(data, filename=output, auto_open=False)

View File

@ -25,9 +25,8 @@ __copyright__ = '(C) 2013, Victor Olaya'
__revision__ = '$Format:%H$'
import matplotlib.pyplot as plt
import matplotlib.pylab as lab
import numpy as np
import plotly as plt
import plotly.graph_objs as go
from processing.core.GeoAlgorithm import GeoAlgorithm
from processing.core.parameters import ParameterTable
@ -43,8 +42,7 @@ class MeanAndStdDevPlot(GeoAlgorithm):
INPUT = 'INPUT'
OUTPUT = 'OUTPUT'
NAME_FIELD = 'NAME_FIELD'
MEAN_FIELD = 'MEAN_FIELD'
STDDEV_FIELD = 'STDDEV_FIELD'
VALUE_FIELD = 'VALUE_FIELD'
def defineCharacteristics(self):
self.name, self.i18n_name = self.trAlgorithm('Mean and standard deviation plot')
@ -55,10 +53,8 @@ class MeanAndStdDevPlot(GeoAlgorithm):
self.addParameter(ParameterTableField(self.NAME_FIELD,
self.tr('Category name field'), self.INPUT,
ParameterTableField.DATA_TYPE_ANY))
self.addParameter(ParameterTableField(self.MEAN_FIELD,
self.tr('Mean field'), self.INPUT))
self.addParameter(ParameterTableField(self.STDDEV_FIELD,
self.tr('StdDev field'), self.INPUT))
self.addParameter(ParameterTableField(self.VALUE_FIELD,
self.tr('Value field'), self.INPUT))
self.addOutput(OutputHTML(self.OUTPUT, self.tr('Plot')))
@ -66,22 +62,24 @@ class MeanAndStdDevPlot(GeoAlgorithm):
layer = dataobjects.getObjectFromUri(
self.getParameterValue(self.INPUT))
namefieldname = self.getParameterValue(self.NAME_FIELD)
meanfieldname = self.getParameterValue(self.MEAN_FIELD)
stddevfieldname = self.getParameterValue(self.STDDEV_FIELD)
valuefieldname = self.getParameterValue(self.VALUE_FIELD)
output = self.getOutputValue(self.OUTPUT)
values = vector.values(layer, namefieldname, meanfieldname, stddevfieldname)
plt.close()
ind = np.arange(len(values[namefieldname]))
width = 0.8
plt.bar(ind, values[meanfieldname], width, color='r',
yerr=values[stddevfieldname],
error_kw=dict(ecolor='yellow'),
)
values = vector.values(layer, namefieldname, valuefieldname)
plt.xticks(ind, values[namefieldname], rotation=45)
plotFilename = output + '.png'
lab.savefig(plotFilename)
with open(output, 'w') as f:
f.write('<html><img src="' + plotFilename + '"/></html>')
d = {}
for i in range(len(values[namefieldname])):
v = values[namefieldname][i]
if v not in d:
d[v] = [values[valuefieldname][i]]
else:
d[v].append(values[valuefieldname][i])
data = []
for k, v in d.items():
data.append(go.Box(y=list(v),
boxmean='sd',
name=k
))
plt.offline.plot(data, filename=output, auto_open=False)

View File

@ -25,17 +25,15 @@ __copyright__ = '(C) 2013, Victor Olaya'
__revision__ = '$Format:%H$'
import matplotlib.pyplot as plt
import matplotlib.pylab as lab
from matplotlib.pyplot import figure
import plotly as plt
import plotly.graph_objs as go
import numpy as np
from processing.core.GeoAlgorithm import GeoAlgorithm
from processing.core.parameters import ParameterTable
from processing.core.parameters import ParameterTableField
from processing.core.outputs import OutputHTML
from processing.tools import vector
from processing.tools import dataobjects
from processing.tools import dataobjects, vector
class PolarPlot(GeoAlgorithm):
@ -66,16 +64,8 @@ class PolarPlot(GeoAlgorithm):
output = self.getOutputValue(self.OUTPUT)
values = vector.values(layer, namefieldname, valuefieldname)
plt.close()
fig = figure(figsize=(8, 8))
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], polar=True)
N = len(values[valuefieldname])
theta = np.arange(0.0, 2 * np.pi, 2 * np.pi / N)
radii = values[valuefieldname]
width = 2 * np.pi / N
ax.bar(theta, radii, width=width, bottom=0.0)
plotFilename = output + '.png'
lab.savefig(plotFilename)
with open(output, 'w') as f:
f.write('<html><img src="' + plotFilename + '"/></html>')
values = vector.values(layer, valuefieldname)
data = [go.Area(r=values[valuefieldname],
t=np.degrees(np.arange(0.0, 2 * np.pi, 2 * np.pi / len(values[valuefieldname]))))]
plt.offline.plot(data, filename=output, auto_open=False)

View File

@ -28,11 +28,10 @@ __revision__ = '$Format:%H$'
import os
try:
import matplotlib.pyplot
assert matplotlib # NOQA silence pyflakes
hasMatplotlib = True
import plotly
hasPlotly = True
except:
hasMatplotlib = False
hasPlotly = False
from qgis.PyQt.QtGui import QIcon
@ -259,7 +258,7 @@ class QGISAlgorithmProvider(AlgorithmProvider):
FixGeometry(), ExecuteSQL(), FindProjection()
]
if hasMatplotlib:
if hasPlotly:
from .VectorLayerHistogram import VectorLayerHistogram
from .RasterLayerHistogram import RasterLayerHistogram
from .VectorLayerScatterplot import VectorLayerScatterplot
@ -267,13 +266,12 @@ class QGISAlgorithmProvider(AlgorithmProvider):
from .BarPlot import BarPlot
from .PolarPlot import PolarPlot
self.alglist.extend([
VectorLayerHistogram(), RasterLayerHistogram(),
VectorLayerScatterplot(), MeanAndStdDevPlot(), BarPlot(),
PolarPlot(),
])
self.alglist.extend([VectorLayerHistogram(), RasterLayerHistogram(),
VectorLayerScatterplot(), MeanAndStdDevPlot(),
BarPlot(), PolarPlot()])
self.externalAlgs = [] # to store algs added by 3rd party plugins as scripts
# to store algs added by 3rd party plugins as scripts
self.externalAlgs = []
folder = os.path.join(os.path.dirname(__file__), 'scripts')
scripts = ScriptUtils.loadFromFolder(folder)

View File

@ -27,27 +27,21 @@ __copyright__ = '(C) 2013, Victor Olaya'
__revision__ = '$Format:%H$'
import matplotlib.pyplot as plt
import matplotlib.pylab as lab
from qgis.PyQt.QtCore import QVariant
from qgis.core import QgsField
import plotly as plt
import plotly.graph_objs as go
from processing.core.GeoAlgorithm import GeoAlgorithm
from processing.core.parameters import ParameterNumber
from processing.core.parameters import ParameterRaster
from processing.core.outputs import OutputTable
from processing.core.outputs import OutputHTML
from processing.tools import dataobjects
from processing.tools import raster
from processing.tools import dataobjects, raster
class RasterLayerHistogram(GeoAlgorithm):
INPUT = 'INPUT'
PLOT = 'PLOT'
TABLE = 'TABLE'
BINS = 'BINS'
PLOT = 'PLOT'
def defineCharacteristics(self):
self.name, self.i18n_name = self.trAlgorithm('Raster layer histogram')
@ -59,33 +53,22 @@ class RasterLayerHistogram(GeoAlgorithm):
self.tr('Number of bins'), 2, None, 10))
self.addOutput(OutputHTML(self.PLOT, self.tr('Histogram')))
self.addOutput(OutputTable(self.TABLE, self.tr('Table')))
def processAlgorithm(self, feedback):
layer = dataobjects.getObjectFromUri(
self.getParameterValue(self.INPUT))
nbins = self.getParameterValue(self.BINS)
outputplot = self.getOutputValue(self.PLOT)
outputtable = self.getOutputFromName(self.TABLE)
values = raster.scanraster(layer, feedback)
output = self.getOutputValue(self.PLOT)
# ALERT: this is potentially blocking if the layer is too big
plt.close()
values = raster.scanraster(layer, feedback)
valueslist = []
for v in values:
if v is not None:
valueslist.append(v)
(n, bins, values) = plt.hist(valueslist, nbins)
fields = [QgsField('CENTER_VALUE', QVariant.Double),
QgsField('NUM_ELEM', QVariant.Double)]
writer = outputtable.getTableWriter(fields)
for i in range(len(values)):
writer.addRecord([str(bins[i]) + '-' + str(bins[i + 1]), n[i]])
plotFilename = outputplot + '.png'
lab.savefig(plotFilename)
with open(outputplot, 'w') as f:
f.write('<html><img src="' + plotFilename + '"/></html>')
data = [go.Histogram(x=valueslist,
nbinsx=nbins)]
plt.offline.plot(data, filename=output, auto_open=False)

View File

@ -25,8 +25,8 @@ __copyright__ = '(C) 2013, Victor Olaya'
__revision__ = '$Format:%H$'
import matplotlib.pyplot as plt
import matplotlib.pylab as lab
import plotly as plt
import plotly.graph_objs as go
from processing.core.GeoAlgorithm import GeoAlgorithm
from processing.core.parameters import ParameterVector
@ -66,9 +66,7 @@ class VectorLayerHistogram(GeoAlgorithm):
output = self.getOutputValue(self.OUTPUT)
values = vector.values(layer, fieldname)
plt.close()
plt.hist(values[fieldname], bins)
plotFilename = output + '.png'
lab.savefig(plotFilename)
with open(output, 'w') as f:
f.write('<html><img src="' + plotFilename + '"/></html>')
data = [go.Histogram(x=values[fieldname],
nbinsx=bins)]
plt.offline.plot(data, filename=output, auto_open=False)

View File

@ -25,8 +25,8 @@ __copyright__ = '(C) 2013, Victor Olaya'
__revision__ = '$Format:%H$'
import matplotlib.pyplot as plt
import matplotlib.pylab as lab
import plotly as plt
import plotly.graph_objs as go
from processing.core.GeoAlgorithm import GeoAlgorithm
from processing.core.parameters import ParameterVector
@ -51,10 +51,12 @@ class VectorLayerScatterplot(GeoAlgorithm):
self.addParameter(ParameterVector(self.INPUT,
self.tr('Input layer')))
self.addParameter(ParameterTableField(self.XFIELD,
self.tr('X attribute'), self.INPUT,
self.tr('X attribute'),
self.INPUT,
ParameterTableField.DATA_TYPE_NUMBER))
self.addParameter(ParameterTableField(self.YFIELD,
self.tr('Y attribute'), self.INPUT,
self.tr('Y attribute'),
self.INPUT,
ParameterTableField.DATA_TYPE_NUMBER))
self.addOutput(OutputHTML(self.OUTPUT, self.tr('Scatterplot')))
@ -68,11 +70,7 @@ class VectorLayerScatterplot(GeoAlgorithm):
output = self.getOutputValue(self.OUTPUT)
values = vector.values(layer, xfieldname, yfieldname)
plt.close()
plt.scatter(values[xfieldname], values[yfieldname])
plt.ylabel(yfieldname)
plt.xlabel(xfieldname)
plotFilename = output + '.png'
lab.savefig(plotFilename)
with open(output, 'w') as f:
f.write('<html><img src="' + plotFilename + '"/></html>')
data = [go.Scatter(x=values[xfieldname],
y=values[yfieldname],
mode='markers')]
plt.offline.plot(data, filename=output, auto_open=False)