-
-
Notifications
You must be signed in to change notification settings - Fork 498
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Serialization Error When Visualizing PyDeck TextLayer #5346
Comments
I've proposed a solution on Discourse. Would like to know if it solves the issue? https://discourse.holoviz.org/t/pydeck-textlayer-in-panel/5790/2 |
@MarcSkovMadsen Not yet. I replied on Discourse and shared a notebook for you to try on your end. |
@MarcSkovMadsen FYI I just tried realizing a TextLayer with a JSON spec fed directly to Panel and that seems to work. This provides an interim workaround. |
Could you share a json spec that works? |
@MarcSkovMadsen Here's an example.
|
I'm realizing now that the JSON spec approach doesn't allow me to move forward with what I want to build. Not easily anyhow when I'm dynamically updating a stack of layers based on user interaction. If there's some possible pathway to get over this serialization hump @MarcSkovMadsen, I'm all ears. |
Hi @diehl You also put in https://gist.github.com/diehl/4a3af23416c2f5e6e65b3ed6bf00833f. Thanks. But its the same |
Hi @MarcSkovMadsen, What I'm trying to avoid is having to actively manage / update a JSON specification as opposed to working with PyDeck layer objects as I update the DeckGL visualization based on user interaction. Right now, I'm blocked from doing that when a TextLayer is in the mix due to the serialization error that comes up when you pass the Deck object to |
Ok the serialization issue I proposed seems to fix one issue. I've found another issue. Currently you have to set the mapbox_key on the PyDeck object because if not the code below will set the A third issue is that currently you will have to set the view_state = pdk.ViewState(latitude=37.7749295, longitude=-122.4194155, zoom=10, bearing=0, pitch=0, min_zoom=1, max_zoom=16) Still finding the last issues. |
@MarcSkovMadsen Awesome! I think I encountered that zoom issue when I was getting a world map with nothing visible on it. I had no ability to zoom in. |
The last thing to figure out (I believe) is why inlining the data in the TextLayer does not work with Panel import pandas as pd
import panel as pn
import pydeck as pdk
from bokeh.core.serialization import Serializer
from pydeck.types import String
MAPBOX_KEY = (
"pk.eyJ1IjoicGFuZWxvcmciLCJhIjoiY2s1enA3ejhyMWhmZjNobjM1NXhtbWRrMyJ9.B_frQsAVepGIe-HiOJeqvQ"
)
data = {
"initialViewState": {
"bearing": 0,
"longitude": -122.418466,
"latitude": 37.752254,
"pitch": 0,
"zoom": 14
},
"layers": [
{
"@@type": "TextLayer",
"data": [
{
"name": "Lafayette (LAFY)",
"code": "LF",
"address": "3601 Deer Hill Road, Lafayette CA 94549",
"entries": 3481,
"exits": 3616,
"coordinates": [-122.123801, 37.893394]
},
{
"name": "12th St. Oakland City Center (12TH)",
"code": "12",
"address": "1245 Broadway, Oakland CA 94612",
"entries": 13418,
"exits": 13547,
"coordinates": [-122.271604, 37.803664]
},
{
"name": "16th St. Mission (16TH)",
"code": "16",
"address": "2000 Mission Street, San Francisco CA 94110",
"entries": 12409,
"exits": 12351,
"coordinates": [-122.419694, 37.765062]
},
{
"name": "19th St. Oakland (19TH)",
"code": "19",
"address": "1900 Broadway, Oakland CA 94612",
"entries": 13108,
"exits": 13090,
"coordinates": [-122.269029, 37.80787]
},
{
"name": "24th St. Mission (24TH)",
"code": "24",
"address": "2800 Mission Street, San Francisco CA 94110",
"entries": 12817,
"exits": 12529,
"coordinates": [-122.418466, 37.752254]
}
],
"getText": "@@=name",
"getPosition": "@@=coordinates",
"getSize": 160,
"getColor": [0, 0, 0],
"getAngle": 0,
"sizeUnits": "meters",
"id": "8a553b25-ef3a-489c-bbe2-e102d18a3211"
}
],
"mapProvider": "carto",
"mapStyle": "https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json",
"views": [{"@@type": "MapView", "controller": True}]
}
# data["layers"][0]["data"]="https://raw.githubusercontent.com/visgl/deck.gl-data/master/website/bart-stations.json"
pn.extension("deckgl")
pn.pane.DeckGL(data, mapbox_api_key=MAPBOX_KEY, sizing_mode="stretch_both").servable() If you don't inline by uncommenting data["layers"][0]["data"]="https://raw.githubusercontent.com/visgl/deck.gl-data/master/website/bart-stations.json" |
I've tried using the inlined json specification at. And it works. So I believe the issue is on the Panel side and not deckgl side. {
"initialViewState": {
"bearing": 0,
"longitude": -122.418466,
"latitude": 37.752254,
"pitch": 0,
"zoom": 14
},
"layers": [
{
"@@type": "TextLayer",
"data": [
{
"name": "Lafayette (LAFY)",
"code": "LF",
"address": "3601 Deer Hill Road, Lafayette CA 94549",
"entries": 3481,
"exits": 3616,
"coordinates": [-122.123801, 37.893394]
},
{
"name": "12th St. Oakland City Center (12TH)",
"code": "12",
"address": "1245 Broadway, Oakland CA 94612",
"entries": 13418,
"exits": 13547,
"coordinates": [-122.271604, 37.803664]
},
{
"name": "16th St. Mission (16TH)",
"code": "16",
"address": "2000 Mission Street, San Francisco CA 94110",
"entries": 12409,
"exits": 12351,
"coordinates": [-122.419694, 37.765062]
},
{
"name": "19th St. Oakland (19TH)",
"code": "19",
"address": "1900 Broadway, Oakland CA 94612",
"entries": 13108,
"exits": 13090,
"coordinates": [-122.269029, 37.80787]
},
{
"name": "24th St. Mission (24TH)",
"code": "24",
"address": "2800 Mission Street, San Francisco CA 94110",
"entries": 12817,
"exits": 12529,
"coordinates": [-122.418466, 37.752254]
}
],
"getText": "@@=name",
"getPosition": "@@=coordinates",
"getSize": 160,
"getColor": [0, 0, 0],
"getAngle": 0,
"sizeUnits": "meters",
"id": "8a553b25-ef3a-489c-bbe2-e102d18a3211"
}
],
"mapProvider": "carto",
"mapStyle": "https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json",
"views": [{"@@type": "MapView", "controller": true}]
} |
You can workaround this issue by specifying import pandas as pd
import panel as pn
import pydeck as pdk
from bokeh.core.serialization import Serializer
from pydeck.types import String
MAPBOX_KEY = (
"pk.eyJ1IjoicGFuZWxvcmciLCJhIjoiY2s1enA3ejhyMWhmZjNobjM1NXhtbWRrMyJ9.B_frQsAVepGIe-HiOJeqvQ"
)
data = {
"initialViewState": {
"bearing": 0,
"longitude": -122.418466,
"latitude": 37.752254,
"pitch": 0,
"zoom": 14
},
"layers": [
{
"@@type": "TextLayer",
"data": [
{
"name": "24th St. Mission (24TH)",
"code": "24",
"address": "2800 Mission Street, San Francisco CA 94110",
"entries": 12817,
"exits": 12529,
"lat": -122.418466,
"lon": 37.752254
}
],
"getText": "@@=name",
"getPosition": "@@=[lat,lon]",
"getSize": 160,
"getColor": [0, 0, 0],
"getAngle": 0,
"sizeUnits": "meters",
"id": "8a553b25-ef3a-489c-bbe2-e102d18a3211"
}
],
"mapProvider": "carto",
"mapStyle": "https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json",
"views": [{"@@type": "MapView", "controller": True}]
}
# data["layers"][0]["data"]="https://raw.githubusercontent.com/visgl/deck.gl-data/master/website/bart-stations.json"
pn.extension("deckgl")
pn.pane.DeckGL(data, mapbox_api_key=MAPBOX_KEY, sizing_mode="stretch_both").servable() |
@MarcSkovMadsen Awesome progress! I've got another example I've been experimenting with on my end where the Panel viz fails to come up as expected when the PyDeck Deck object is passed to
And sure enough, your code above held the answer. By inserting the API key into the |
WorkaroundThis example will workaround the issues with 1) mapbox key 2) min/ max zoom and 3) no support for array columns. I've marked the points with import pandas as pd
import pydeck as pdk
from bokeh.core.serialization import Serializer
from pydeck.types import String
def pydeck_string_encoder(obj, serializer):
return obj.value
Serializer._encoders[String] = pydeck_string_encoder
TEXT_LAYER_DATA = "https://raw.githubusercontent.com/visgl/deck.gl-data/master/website/bart-stations.json" # noqa
MAPBOX_KEY = "pk.eyJ1IjoicGFuZWxvcmciLCJhIjoiY2s1enA3ejhyMWhmZjNobjM1NXhtbWRrMyJ9.B_frQsAVepGIe-HiOJeqvQ"
df = pd.read_json(TEXT_LAYER_DATA)
# Workaround
lat_lon = pd.DataFrame(df["coordinates"].to_list(), columns=["lat", "lon"])
del df["coordinates"]
df = pd.concat([df, lat_lon], axis=1)
# Define a layer to display on a map
layer = pdk.Layer(
"TextLayer",
df,
pickable=True,
get_position="[lat,lon]", # Workaround
get_text="name",
get_size=160,
get_color=[0, 0, 0],
get_angle=0,
get_text_anchor=String("middle"),
get_alignment_baseline=String("center"),
size_units=String("meters"),
api_keys={"mapbox": MAPBOX_KEY}, # Workaround
)
# Set the viewport location
view_state = pdk.ViewState(
latitude=37.7749295,
longitude=-122.4194155,
zoom=11,
bearing=0,
pitch=0,
min_zoom=0, # Workaround
max_zoom=16, # Workaround
)
# Render
r = pdk.Deck(
layers=[layer],
initial_view_state=view_state,
tooltip={"text": "{name}\n{address}"},
map_style=pdk.map_styles.ROAD,
)
import panel as pn
pn.extension("deckgl")
pn.pane.DeckGL(
r, mapbox_api_key=MAPBOX_KEY, sizing_mode="stretch_both"
).servable() |
@MarcSkovMadsen Awesome! Just added the serialization code to my example and now the JSON spec step is not needed. Thank you sir for this workaround! Do you plan to roll the serialization code into Panel somehow so that it will not be necessary in the future when running code such as the above? |
ALL software version info
PyDeck 0.8, Panel 1.2
Description of expected behavior and the observed behavior
I recently coded up a variation of the PyDeck TextLayer example from the PyDeck website and then attempted to integrate that into a Panel application. Panel is having a serialization issue with the PyDeck String type.
Complete, minimal, self-contained example code that reproduces the issue
This Google Colab notebook shows the visualization running without issue in PyDeck and then shows my attempt to render that same visualization via Panel.
The text was updated successfully, but these errors were encountered: