In the previous section, we viewed vector layer fields and attributes. Now let’s use these attributes to put a filter on our layer so that it only contains certain features.

For example, this is how we can filter our countries vector layer to only features where the ADMIN value starts with an A:

vlayer.setSubsetString("ADMIN LIKE 'A%'")
for feature in vlayer.getFeatures():

This code is the equivalent of going to the layer properties and entering ADMIN LIKE ‘A%’ in the provider feature filter.

To remove the filter, we set an empty subset string:

for feature in vlayer.getFeatures():

To make our code more flexible, we can use a variable to define the character we want to filter for. The advantage of using a variable is that we only need to define it once and then we can use it in multiple places within our code. And if we eventually want to change it to a different character, we only have to change it in one place. The following code shows two different approaches for inserting a variable into a string:

my_char = "C"
vlayer.setSubsetString("ADMIN LIKE '"+my_char+"%'")
print("The following country names start with {}:".format(my_char))
for feature in vlayer.getFeatures():

The first approach is to concatenate strings using + operators. The second approach is called string formatting and the above syntax (with curly brackets) is specific to Python 3 (and thus requires QGIS 3).

String formatting looks complicated at first sight but it is also really powerful. For example, we can output the number of people living in each country using:

for feature in vlayer.getFeatures():
    print("{pop:.2f} mio people live in {name}".format(name=feature['ADMIN'],pop=feature['POP_EST']/1000000))

4.51 mio people live in Central African Republic
33.49 mio people live in Canada
16.60 mio people live in Chile

This is interesting for multiple reasons: first, the parameters in the format function can be provided in any order because we assigned them names (pop and name in this example). Second, we formatted the population value to display two digits after the decimal separator. For more string formatting examples see the official Python documentation.

This is one way to filter the features in a vector layer. You also saw some different methods for integrating variables into strings using either the + operator or string formatting.


PyQGIS 101 is a work in progress. I’d appreciate any feedback, particularly from beginners!

  1. Kurt said:

    my_char = “C”
    vlayer.setSubsetString(“ADMIN LIKE ‘”+my_char+”%'”)
    print(“The following country names start with {}:”.format(my_char))
    for feature in vlayer.getFeatures():

    why does replacing the first line of code from above with
    my_char = input(“Enter Char”)
    not work?

    • I assume input(“Enter Char”) is an attempt to make the script interactive but this is not the way to achieve interactivity in PyQGIS. I’ll definitely get into this topic later.

  2. Hi, I can’t differentiate the “two approaches” that you mention above. Can you please be more specific?

    Thanks, I’m learning a lot!

    • Approach #1 is string concatenation using + operators:
      "ADMIN LIKE '"+my_char+"%'"

      Approach #2 is string formatting:
      "ADMIN LIKE '{}%'".format(my_char)

  3. I hit my first major challenge here. I’ve never thought of using LIKE in the query builder. I don’t think I ever noticed its existence until this tutorial.

    So, I had to google it, the search led me to learning about wildcards.

    Also, the formatting was challenging but now I love it.

    Lastly, and this is a question, how do I tell qgis to perform a function on an already added layer instead of creating a new layer every time I update my code?

    Thanks ma’am for the benefits.

    • You can use vlayer=iface.activeLayer() to the currently active loaded layer.

  4. Luc said:

    According to the previous part of the tutorial and from what I’ve understood, I suggest to replace (in the project already containing ne_10m_admin_0_countrie
    the “vlayer = iface.addVectorLayer(path, “countries”, “ogr”)”
    by “vlayer=iface.activeLayer()”

  5. Hello, Thanks for the tutorial I am a beginner,

    I try string formatting, but I have this error

    UnicodeEncodeError: ‘ascii’ codec can’t encode character u’\xe9′ in position 10: ordinal not in range(128).

    Please help me. Thanks

    • sniperleonidas said:

      I try to put # -*- coding: utf-8 -*- as first line of the script but its does’nt work.

  6. Claudia said:

    Hi, I could not find ‘SetSubsetString’ option through the list. I am working with QGIS 2.18, How can I solve this problem?

    • These tutorials require QGIS3. The PyQGIS API has changed.

  7. Paweł Swoboda said:

    Hi thank you for your blog, it’s very helpful. Unfortunately QGIS Filter still has an unsolved bug – LIKE operator is not case-sensitive.
    For example:

    vlayer.setSubsetString(“FIELD_NAME LIKE ‘%Wola'”)

    returns features where the FIELD_NAME values ends with ‘wola’, e.g. Tywola, Suchowola etc.
    Is it possible to run setSubsetString function using re.match or regexp_match or anything similar?

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: