ghtmtt / dataplotly Goto Github PK
View Code? Open in Web Editor NEWD3 like plots creation with plotly in QGIS
License: GNU General Public License v2.0
D3 like plots creation with plotly in QGIS
License: GNU General Public License v2.0
add a checkbox to let the user choose to display the labels on the points in the plot
A bit complicated to implement, but the code is more or less straightforward:
f1 = [125.7, 219.12, 298.55, 132.32, 520.6, 3435.49, 2322.61, 1891.63, 216.97, 383.98, 82.01, 365.56, 199.98, 308.71, 217.58, 436.09, 711.77]
f2 = [1046.67, 1315.0, 1418.0, 997.33, 2972.3, 9700.0, 6726.0, 6002.5, 2096.0, 2470.0, 867.0, 2201.7, 1685.6, 2416.7, 1618.3, 2410.0, 2962.0]
trace1 = go.Scatter(
x = f1,
y = f2,
mode = 'markers'
)
layout = go.Layout(
xaxis = dict(range=[min(f1), max(f1)], autorange=False),
yaxis = dict(range=[min(f2), max(f2)], autorange=False),
updatemenus = [{'type': 'buttons', 'buttons':
[{'label': 'Play',
'method': 'animate',
'args': [None]},
{'label': 'Pause',
'method': 'animate',
'args': [[None],
{'frame' : {'duration':0, 'redraw': False}, 'mode':'immediate'},
]}
]}],
)
frames= []
for i, j in zip(f1, f2):
frames.append({'data': [{'x': [i], 'y': [j]}]})
data = [trace1]
fig = go.Figure(data=data, layout = layout, frames=frames)
plotly.offline.plot(fig)
API here
https://plot.ly/python/animations/#moving-frenet-frame-along-a-planar-curve
Cool, see here https://plot.ly/python/heatmap-webgl/
BTW: check with a small example if the QWebView loads the plot (#13)
This happens because each plot has its own Layout
while to create stack or overlay histograms the layout must be just one..
This sounds like a small code reviewing...
From version 2.0.12 the facet plotting is available. A third variable can be used for plotting just the category:
https://plot.ly/python/facet-trellis/
seems very easy to implement, but be aware of the plotly version installed
Some more options to add, especially some default color scale
Don't know if also additional and optional X and Y field could be added instead of just Z
Problem with the plot and the QWebView is the html generated. By avoiding to export the javascript into the html and adding just the link to it, it works nice in the QWebView.
Something like this:
self.plot_html = '<head><meta charset="utf-8" /></head>''<head><meta charset="utf-8" /><script src="https://cdn.plot.ly/plotly-latest.min.js"></script></head>'
self.plot_html += plotly.offline.plot(fig, output_type='div', include_plotlyjs=False)
self.plot_html += '</body></html>'
tmp
folder (see also #6)THE BUTTON TO SAVE THE PLOT STILL DOES NOT WORK, so find a way to a way to add a button to take a screenshot of the webview
Infrastructure is ready for both UI and help.
See here how to translate the UI: http://docs.qgis.org/testing/en/docs/pyqgis_developer_cookbook/plugins.html#translation
and follow the standard sphinx instructions for the help system: http://www.sphinx-doc.org/en/stable/intl.html
When subplotting in rows or columns from different vector sources, the selection tool works only of the last vector (so last plot) and the first one is ignored.
Currently in dialog
the js callback function works like this:
if dic['mode'] == 'selection':
if dic['type'] == 'scatter':
self.layer_combo.currentLayer().selectByIds(dic['id'])
else:
self.layer_combo.currentLayer().selectByIds(dic['tid'])
maybe in plot
, together with the other variables takes also the QgsVectorLayer
object should be taken.
With the new UI all the new strings have to be pushed to transifex
The current Plot Basket
tab is useless because the remove trace button is not doing anything.
Maybe by removing the tab and all the options related the layout of the plugin will be cleaner and maybe that options are not super useful for the users.
having just the Clean Plot Canvas
and Create Plot
buttons is good, but maybe it is worth, when the first plot is created (i.e. Create Plot
is hit the first time) to give some option to overlap the plots (SinglePlot
)or put the other plots in rows and columns (SubPlots
)
Could be a chance to embed the plot in some websites or other.
Plot is fine but it needs some love:
If the plot is made with the selected features
checkbox, the expression (and the selection) is correct, but it loops in all the attribute table and not just in the feature subset.
Handling this is quite tricky.
Should not be super exhaustive, but needed.
Should be quite easy, check the old code:
It is really worth to add a third optional field (like a fake Z Field) for the hovering over the points in the map (Mg vs Ca and hover will display the ID of the point).
dx
and dy
axis start and stop (like ranges) boxes?Check the behavior and avoid Stack Traces
Could be useful with some common issues (especially installation troubles).
Refer to this first: #47
Should be easy to fix:
Traceback (most recent call last):
File "/home/matteo/.local/share/QGIS/QGIS3/profiles/matteo/python/plugins/DataPlotly/data_plotly_dialog.py", line 750, in createPlot
self.plotProperties()
File "/home/matteo/.local/share/QGIS/QGIS3/profiles/matteo/python/plugins/DataPlotly/data_plotly_dialog.py", line 675, in plotProperties
'featureBox':getSortedId(self.layer_combo.currentLayer(), xx),
File "/home/matteo/.local/share/QGIS/QGIS3/profiles/matteo/python/plugins/DataPlotly/utils.py", line 53, in getSortedId
if type(field_list[0]) == (int or float):
IndexError: list index out of range
Consider to change how to save the images also using directly plotly API: https://plot.ly/python/static-image-export/
Could be tricky for subplotting or for more plot in the same plot canvas.
Small code sample:
import plotly
import plotly.graph_objs as go
vl = iface.activeLayer()
f1 = []
for i in vl.getFeatures():
f1.append(i['PH'])
f2 = []
for i in vl.getFeatures():
f2.append(i['EC'])
trace1 = go.Scatter(
x = f1,
y = f2
)
layout = go.Layout(
showlegend = True
)
data = [trace1]
fig = go.Figure(data=data, layout = layout)
plotly.offline.plot(fig, image='svg')
I just installed 2.99 on linux 17.10. I tired to install the plugin and got the following error -
Couldn't load plugin 'DataPlotly' due to an error when calling its classFactory() method
ModuleNotFoundError: No module named 'PyQt5.QtWebKit'
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/qgis/utils.py", line 336, in startPlugin
plugins[packageName] = package.classFactory(iface)
File "/home/uncle/.local/share/QGIS/QGIS3/profiles/default/python/plugins/DataPlotly/init.py", line 34, in classFactory
from .data_plotly import DataPlotly
File "/usr/lib/python3/dist-packages/qgis/utils.py", line 664, in _import
mod = _builtin_import(name, globals, locals, fromlist, level)
File "/home/uncle/.local/share/QGIS/QGIS3/profiles/default/python/plugins/DataPlotly/data_plotly.py", line 30, in
from DataPlotly.data_plotly_dialog import DataPlotlyDockWidget
File "/usr/lib/python3/dist-packages/qgis/utils.py", line 664, in _import
mod = _builtin_import(name, globals, locals, fromlist, level)
File "/home/uncle/.local/share/QGIS/QGIS3/profiles/default/python/plugins/DataPlotly/data_plotly_dialog.py", line 31, in
from PyQt5.QtWebKit import QWebSettings
File "/usr/lib/python3/dist-packages/qgis/utils.py", line 664, in _import
mod = _builtin_import(name, globals, locals, fromlist, level)
ModuleNotFoundError: No module named 'PyQt5.QtWebKit'
Coherence with basket used in the code
QgsDataDefinedButton
does not exist anymore, it has been replaced with QgsPropertyOverrideButton
: http://qgis.org/api/classQgsPropertyOverrideButton.html
here a code snippet to run it from the python console:
from qgis.gui import QgsPropertyOverrideButton
btn = QgsPropertyOverrideButton()
btn.show()
and here an old question on how to connect the vector layer to the button: https://gis.stackexchange.com/questions/193120/how-to-connect-qgsmaplayercombobox-to-qgsdatadefinedbutton
When subplotting many plots, if one of this is pie plots it won't work because of the plotly code.
Add some message to inform the user
currently every layer is loaded, also rasters
What about adding mean and stdev lines in a plot? Seems simple with shapes
https://plot.ly/python/shapes/
at least for scatterplot and histograms. Code snippet:
layout = {
"shapes": [
{
"fillcolor": "blue",
"line": {
"color": "blue",
"width": 1
},
"type": "line",
"x0": -90422231,
"x1": 3104496578,
"xref": "x",
"y0": 5,
"y1": 5,
"yref": "y"
}
]}
Documentation should be updated with:
Easy to go:
https://plot.ly/python/reference/#histogram-nbinsx
nbinsx = 10
just be careful with the box orientation
the tmp
folder is the best solution at the moment.
NOTE make it cross platform!
Packaging the zip with 3 language is too big (>20MB). Sphinx framework should be reviewed
Apparently the code works (dict is filled with correct values etc), the base plot (grid, axes, etc) is visible in the QWebView, but no points or lines appear in the plot.
This happens with the following:
Not working solution it to locally save the plotly.js
file and load it in the html file. In this case nothing is loaded in the QWebView
Easy to go. Should also not be tricky with orientation:
data = [go.Histogram(x=x, cumulative=dict(enabled=True))]
When clicking the Update Plot
button an additional plot is added to the plot canvas.
Instead, the last plot created has to be edited
In a future automated tests have to be added. Not a simple process (especially with Travis). Some references:
https://snorfalorpagus.net/blog/2014/01/04/writing-unit-tests-for-qgis-python-plugins/
https://github.com/boundlessgeo/qgis-testing-environment-docker
https://boundlessgeo.com/2016/07/qgis-continuous-integration-testing-environment-for-python-plugins/
Currently the expression on the fields are not supported.
Scatter3D plots are in the plots
folder and ready to use. Work fine except when emptying the plot basket or removing a single 3D trace (or having some normal error when overlapping different plots).
QGIS crashed (also on WIN), difficult to understand the cause:
QGIS died on signal 11Could not attach to process. If your uid matches the uid of the target
process, check the setting of /proc/sys/kernel/yama/ptrace_scope, or try
again as the root user. For more details, see /etc/sysctl.d/10-ptrace.conf
ptrace: Operation not permitted.
No thread selected
No stack.
gdb returned 0
Aborted
Trying to install the plugin on QGIS 3 built from source I get the following error message - No module named PyQt5.QtWebKit
Running:
QGIS version | 2.99.0-Master | QGIS code revision | a0819053fd |
---|---|---|---|
Compiled against Qt | 5.7.1 | Running against Qt | 5.7.1 |
Compiled against GDAL/OGR | 2.1.2 | Running against GDAL/OGR | 2.1.2 |
Compiled against GEOS | 3.5.1-CAPI-1.9.1 | Running against GEOS | 3.5.1-CAPI-1.9.1 r4246 |
PostgreSQL Client Version | 9.6.5 | SpatiaLite Version | 4.3.0a |
QWT Version | 6.1.2 | PROJ.4 Version | 493 |
QScintilla2 Version | 2.9.3 | This copy of QGIS writes debugging output. |
Any pointers what could be wrong?
button to copy the html code and embed it in the print composer as html frame
In the old plugin it was quite easy, but made with scipy
. Check if scipy
is natively imported in QGIS.
10851ef introduces icons for plot combo, marker and line type
Future problem (with translations) will be the current method implemented to retrieve the object from the second dictionary.
In fact, now the common key is, e.g. for plots, the plot name that is (and should be) translatable:
https://github.com/ghtmtt/DataPlotly/blob/master/data_plotly_dialog.py#L73
Another fixed method has to be implemented.
All the screenshots have to be updated with the new UI
Native plotly save plot button does not work.
Solution is to create an additional button to save the plot as a screenshot of the webview in a folder chosen by the user
Many errors are already handled with the MessageBar widget, some more needed:
Errors:
WebView:
Allow to take into account only the selected features with a checkbox
In could be useful to have also some way to have the plot configurations saved within the project.
The code should allow that easy, but the way to implement it has to be straightforward
Fill the help tab and write a short Readme.md
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.