Skip to content

Commit

Permalink
Merge pull request #4150 from alexbruy/processing-graphs
Browse files Browse the repository at this point in the history
[processing] improve graphs
  • Loading branch information
alexbruy committed Feb 16, 2017
2 parents 35d9b83 + 1d68c16 commit f587ae5
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 111 deletions.
15 changes: 5 additions & 10 deletions python/plugins/processing/algs/qgis/BarPlot.py
Expand Up @@ -25,8 +25,8 @@

__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
Expand Down Expand Up @@ -69,13 +69,8 @@ def processAlgorithm(self, feedback):
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)
48 changes: 23 additions & 25 deletions python/plugins/processing/algs/qgis/MeanAndStdDevPlot.py
Expand Up @@ -25,9 +25,8 @@

__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
Expand All @@ -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')
Expand All @@ -55,33 +53,33 @@ def defineCharacteristics(self):
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')))

def processAlgorithm(self, feedback):
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'),
)

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>')
values = vector.values(layer, namefieldname, valuefieldname)

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)
26 changes: 8 additions & 18 deletions python/plugins/processing/algs/qgis/PolarPlot.py
Expand Up @@ -25,17 +25,15 @@

__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):
Expand Down Expand Up @@ -66,16 +64,8 @@ def processAlgorithm(self, feedback):

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)
20 changes: 9 additions & 11 deletions python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py
Expand Up @@ -28,11 +28,10 @@
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

Expand Down Expand Up @@ -259,21 +258,20 @@ def __init__(self):
FixGeometry(), ExecuteSQL(), FindProjection()
]

if hasMatplotlib:
if hasPlotly:
from .VectorLayerHistogram import VectorLayerHistogram
from .RasterLayerHistogram import RasterLayerHistogram
from .VectorLayerScatterplot import VectorLayerScatterplot
from .MeanAndStdDevPlot import MeanAndStdDevPlot
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)
Expand Down
37 changes: 10 additions & 27 deletions python/plugins/processing/algs/qgis/RasterLayerHistogram.py
Expand Up @@ -27,27 +27,21 @@

__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')
Expand All @@ -59,33 +53,22 @@ def defineCharacteristics(self):
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)
output = self.getOutputValue(self.PLOT)

# ALERT: this is potentially blocking if the layer is too big
values = raster.scanraster(layer, feedback)

# ALERT: this is potentially blocking if the layer is too big
plt.close()
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)
14 changes: 6 additions & 8 deletions python/plugins/processing/algs/qgis/VectorLayerHistogram.py
Expand Up @@ -25,8 +25,8 @@

__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
Expand Down Expand Up @@ -66,9 +66,7 @@ def processAlgorithm(self, feedback):
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)
22 changes: 10 additions & 12 deletions python/plugins/processing/algs/qgis/VectorLayerScatterplot.py
Expand Up @@ -25,8 +25,8 @@

__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
Expand All @@ -51,10 +51,12 @@ def defineCharacteristics(self):
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')))
Expand All @@ -68,11 +70,7 @@ def processAlgorithm(self, feedback):
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)

0 comments on commit f587ae5

Please sign in to comment.