steveberardi / starplot

✨ Star charts and maps in Python
https://starplot.dev
MIT License
17 stars 7 forks source link

label alignment problem #56

Closed EsatAkkasoglu closed 4 months ago

EsatAkkasoglu commented 4 months ago

As you can see in the image below, the names of some constellations are not in the proper position and are difficult to understand. although I read the documentation carefully, I could not get exactly the result I wanted. in addition, there are 2 planets in the west direction and neither of these planets has a name. how can I solve this problem? There is a lot of chaos, especially in the Zenith area.

image

EsatAkkasoglu commented 4 months ago
p = ZenithPlot(lat=observer.latitude.degree, lon=observer.longitude.degree,
                       dt=localtime, limiting_magnitude=4.6, style=style,
                       adjust_text=True, include_info_text=True, ephemeris="de440.bsp",resolution=6096,rasterize_stars=True)
async def plot_style(self):
        style = PlotStyle().extend(extensions.BLUE_MEDIUM, extensions.MAP)
        style.constellation.label.font_size = 11
        style.constellation.line.width= 6
        style.constellation.line.zorder = -1
        style.star.label.font_size= 10
        style.star.marker.size= 50
        style.ecliptic.line.visible = True

        # DSO Configuration
        dso_marker_style = MarkerStyle(
            color="red",
            symbol=MarkerSymbolEnum.TRIANGLE,
            size=10,
            fill=FillStyleEnum.FULL,
            alpha=0.6,
            visible=True,
            zorder=-1,
        )
        dso_label_style = LabelStyle(
            font_color="red",
            font_size=11,
            font_weight="normal",
            font_family="Arial",
            line_spacing=-1,
            zorder=1,
        )
        style.dso.label = dso_label_style
        style.dso.marker = dso_marker_style

        # Planet Configuration
        planet_marker_style = MarkerStyle(
            color="#C0AD00",
            symbol=MarkerSymbolEnum.CIRCLE,
            size=6,
            fill=FillStyleEnum.FULL,
            alpha=0.8,
            visible=True,
            zorder=-1,
        )
        planet_label_style = LabelStyle(
            font_color="#C0AD00",
            font_size=10,
            font_weight="bold",
            font_family="Arial",
            line_spacing=1.0,
            zorder=1,
        )
        style.planets.label = planet_label_style
        style.planets.marker = planet_marker_style

        style 
        # Moon Configuration
        style.moon.marker.visible = True
        return style  
steveberardi commented 4 months ago

@EsatAkkasoglu It looks like a couple things are going on here:

  1. By default, Starplot will hide colliding labels. You can turn this off by passing the kwarg hide_colliding_labels=False to the constructor.
  2. Starplot also uses the adjustText library to adjust labels so they don't overlap (and does so by actually moving labels). By default, this method is not run automatically for plots (largely because it adds a lot of execution time), but you can have it run automatically by passing adjust_text=True to the constructor or run it directly. Looks like you already know about this method though, based on your code.

Both of these methods try to solve the same problem: avoiding too much clutter (and especially overlaps) with labels. They don't always do a great job though, as you've noticed :) I'd recommend trying each method individually, adjusting font sizes for different labels to decrease the chance of overlaps, plotting less objects, increasing the plot's resolution, or as a last resort you could set hide_colliding_labels=False and plot labels explicitly at precise locations.

I'm hoping to improve a lot of the labeling stuff in v0.10.0, but for the next version (0.9.0) I'll at least add kwargs to the adjust_text function so you can configure that library more directly (it has a lot of different features that may help you).

Thanks for sharing your code, makes it a lot easier to see what the issue might be :)

EsatAkkasoglu commented 4 months ago

image I applied the changes you said. and I made some font changes and the result came out this way, there are overlapping writings, but for me the position of the writing was more important. I liked this result more, thanks for your help.

    async def plot_style(self):
        style = PlotStyle().extend(extensions.BLUE_MEDIUM, extensions.MAP)
        style.constellation.label.font_size = 11
        style.constellation.line.width= 6
        style.constellation.line.zorder = -1
        style.star.label.font_family= "monospace"
        style.star.label.font_size= 10
        style.star.marker.size= 50
        style.ecliptic.line.visible = True

        # DSO Configuration
        dso_marker_style = MarkerStyle(
            color="red",
            symbol=MarkerSymbolEnum.TRIANGLE,
            size=10,
            fill=FillStyleEnum.FULL,
            alpha=0.6,
            visible=True,
            zorder=-1,
        )
        dso_label_style = LabelStyle(
            font_color="red",
            font_size=11,
            font_weight="normal",
            font_family="cursive",
            line_spacing=-1,
            zorder=1,
        )
        style.dso.label = dso_label_style
        style.dso.marker = dso_marker_style

        # Planet Configuration
        planet_marker_style = MarkerStyle(
            color="#C0AD00",
            symbol=MarkerSymbolEnum.CIRCLE,
            size=6,
            fill=FillStyleEnum.FULL,
            alpha=0.8,
            visible=True,
            zorder=-1,
        )
        planet_label_style = LabelStyle(
            font_color="#C0AD00",
            font_size=10,
            font_weight="bold",
            font_family="sans-serif",
            line_spacing=1.0,
            zorder=1,
        )
        style.planets.label = planet_label_style
        style.planets.marker = planet_marker_style

        style 
        # Moon Configuration
        style.moon.marker.visible = True
        return style
    async def get_zenith_plot(self, date: str):
        """Returns a zenith plot for the given date.
        Args:
        - date (datetime): The date for which the zenith plot is generated.

        Returns:
        - ZenithPlot: A zenith plot object.
        """
        observer, localtime = await get_observer_and_local_time(self.city, date)
        style = await self.plot_style()
        p = ZenithPlot(lat=observer.latitude.degree, lon=observer.longitude.degree,
                       dt=localtime, limiting_magnitude=5, style=style,
                       adjust_text=False, include_info_text=True, ephemeris="de440.bsp",resolution=6096,rasterize_stars=False,_hide_colliding_labels=False_)
        return p