I'm trying to develop a plugin in QGIS.

My issue is that I don't know how to transform an attribute table into a dataframe in order to use it further in run(self) function later.

I also used a comboBox in order to insert a layer the code below is located in run function:

self.dlg.comboBox.addItems([layer.name() for layer in layers])

I used Plugin Builder and Qt Designer.


You can try:

import pandas as pd
lyr = QgsProject.instance().mapLayersByName('ok_ak_riks')[0]

#List all columns you want to include in the dataframe. I include all with:
cols = [f.name() for f in lyr.fields()] #Or list them manually: ['kommunnamn', 'kkod', ... ]

#A generator to yield one row at a time
datagen = ([f[col] for col in cols] for f in lyr.getFeatures())

df = pd.DataFrame.from_records(data=datagen, columns=cols)

enter image description here


You may use the following code to make the conversion. I make a conversion to a pandas DataFrame and then to a geopandas GeoDataFrame. You may use only first part of the recipe

You can also note that I do not cast each column to pandas dtype completely at the end of the script e.g https://stackoverflow.com/questions/21197774/assign-pandas-dataframe-column-dtypes. To get QGIS column types (human readable), look at unused columns_types in the code. The code to convert from Dataframe to GeoDataFrame is mainly borrowed from official GeoPandas doc section about Creating a GeoDataFrame from WKT format

import pandas as pd
import geopandas
from shapely import wkt

layer = layers[selectedLayerIndex].layer()
# for standalone case, comment above and uncomment below
# layer = iface.activeLayer()

columns = [f.name() for f in layer.fields()] + ['geometry']
columns_types = [f.typeName() for f in layer.fields()] # We exclude the geometry. Human readable
# or
# columns_types = [f.type() for f in layer.fields()] # QVariant type
row_list = []
for f in layer.getFeatures():
    row_list.append(dict(zip(columns, f.attributes() + [f.geometry().asWkt()])))

df = pd.DataFrame(row_list, columns=columns)
df['geometry'] = geopandas.GeoSeries.from_wkt(df['geometry'])
gdf = geopandas.GeoDataFrame(df, geometry='geometry')
gdf = gdf.set_crs(crs=layer.crs().toWkt())

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.