How to increase plot width in Julia Plots.jl without increasing tick line width and the gap between tick and tick axis

Hello,

I want to plot many data points whose x values are very close to each other. To be able to separate them out a little more so that they can be seen more clearly, I want to increase the plot width (it can be much larger than the paper size; I don’t need to print it). I tried the MWE shown below. The problem is that this creates (1) Long tick lines for the y-axis; and (2) Big gap between the tick labels and the axis line.

My main question is:

How can I manipulate both these settings in Plots.jl so that this does not happen? I want the tick labels next to the axis line and tick lines to be smaller. I would really appreciate any help.

Thank you.

module CodeQuestion

import Plots
import Dates
import StatsBase; Sb = StatsBase

function plotdata()
    xtickvals = Dates.DateTime(2020,1,4,0,0,0):Dates.Second(3600):Dates.DateTime(2020,1,5,0,0,0) |> collect
    xvals = Dates.DateTime(2020,1,4,0,0,0):Dates.Second(10):Dates.DateTime(2020,1,5,0,0,0) |> collect
    xvalsplt = Sb.sample(xvals, 6000, replace = false) |> sort
    numobs = length(xvalsplt)
    yvals = [rand(-5:-2) for i = 1:numobs]

    Plots.plot( xvalsplt, yvals, 
                seriestype = :scatter, 
                label = :none, 
                xticks = xtickvals,
                yticks = -10:2.5:0,
                ytickfonthalign = :left,
                left_margin = 20Plots.mm,
                bottom_margin = 40Plots.mm,
                xrotation = 90,
                xlims = [Dates.value(xtickvals[1]), Dates.value(xtickvals[end])],
                ylims = [-10, 1],
                markersize = 4,
                markerstrokecolor = "gray",
                marketstrokewidth = 0.5,
                size = (7200,500))
    Plots.savefig("fig_temp.pdf")
end


end ## end module

I don’t know how to answer your specific question, but maybe I can suggest an alternative. In a Pluto notebook you can add a slider to change the x limits and walk over your data:

https://github.com/lmiq/Work/raw/master/ezgif.com-gif-maker.png

# ╔═╡ bf4ce15c-bb5d-11eb-1544-59e5da109424
using Plots

# ╔═╡ 42e5ad87-62c2-46ce-9c07-3dcc2fa5a024
using Dates

# ╔═╡ 5cf7d1ac-35cd-42fc-b85e-d0934759da69
using StatsBase

# ╔═╡ 24f8bcca-dca8-48f2-80b3-f22200c94f00
xvals = Dates.DateTime(2020,1,4,0,0,0):Dates.Second(10):Dates.DateTime(2020,1,5,0,0,0) |> collect

# ╔═╡ cf88a07e-bb3e-48a4-89a3-36c16bdd00d6
xvalsplt = sample(xvals, 6000, replace = false) |> sort

# ╔═╡ 689c1cb4-1f3a-44c6-86e0-ac1df24e0142
numobs = length(xvalsplt)

# ╔═╡ a578f4dc-d87d-4739-a3d7-66bd4c0f0475
yvals = [rand(-5:-2) for i = 1:numobs]

# ╔═╡ db52bef8-fd6f-4016-a210-a98f3fe1e53b
scatter(xvals,yvals,xlim=[Dates.value(xvals[imin]), Dates.value(xvals[imin+irange])],xrotation=60,label="")

# ╔═╡ 91e505c9-bd5f-4955-bb68-7a3eb467e53a
@bind irange html"<input type='range' min=1 max=length(xvals)>"

# ╔═╡ de5d832e-27e4-480a-b6fa-75e9dd9e4b7e
@bind imin html"<input type='range' min=1 max=length(xvals)>"

# ╔═╡ 350d06f0-74a6-4e71-bd56-3878a8588fb8


1 Like

Thank you very much LeandroMartinez98. This might be an interesting avenue. Still it would be great to learn how to adjust tick position of labels. But will explore this more. I have not used Pluto.jl before. So this is a great way to start exploring it.

Thanks again!

1 Like

(could you see the animation? - just curiosity, I am not sure how to share it here).

To explore the data as you are trying to, it seems a nice option.

I did see it. It is very cool. However, I need to look more into sharing options with it, and see if it would be as easy as sharing a static PDF. But for my own consumption that would have been a good option.

1 Like

Different backends behave differently. For example, InspectDR doesn’t stretch your plot as an image the way the GR backend appears to be doing. Instead, it uses the size = (7200,500) argument to specify the canvas size, and always keeps the same tick length (which is specified in its “Layout” structures).

GR output (Default in Plots.jl)

InspectDR output

If you add the InspectDR package, and the code needed to use it, you get the following:

import StatsBase; Sb = StatsBase
import InspectDR

function plotdata()
    Plots.inspectdr() #Choose InspectDR backend
    #Plots.gr() #Choose GR backend
    xtickvals = Dates.DateTime(2020,1,4,0,0,0):Dates.Second(3600):Dates.DateTime(2020,1,5,0,0,0) |> collect

image

Note that InspectDR doesn’t rotate the x-tick labels at the moment - but I think that it probably works out for the best in this case.

Other backends

You might want to experiment with other backends if you don’t like the InspectDR output. InspectDR is not as customizable as other backends.

1 Like

Sharing PDF

Sharing a PDF is definitely the easiest way to guarantee everyone can read your plots.

Alternative: Sharing .HDF5 plots

Plots.jl has a “HDF5 backend” that allows you to save plots+data as a single .hdf5 file. Using this “backend”, your colleagues can display plots with a simple Julia script without having to re-run your whole algorithm/simulation.

To do this, they would have to install Julia+Plots.jl, and you would have to provide the .hdf5 plot data & a simple load script resembling the one in:
http://docs.juliaplots.org/latest/backends - HDF5-Plots

Caveat: HDF5-Plots is not yet a proper versioned file format. That means your colleagues should use the same version of Plots.jl you used to save the plot. Otherwise, there is a higher chance the data structures won’t match - and the HDF5-Plots backend won’t know how to read the data back in correctly.

Alternative: Hosting a Pluto session

If Pluto works somewhat like Jupyter, you should be able to let colleagues connect to your own Pluto session. Of course, you need to have a machine running Pluto to host this session whenever they need to explore the data (which is non-ideal).

But, by combining this with the HDF5-Plots solution, coworkers wouldn’t need to run your whole algorithm/simulation either.

1 Like

These plotly solutions 1 or 2 look/sound good.

I haven’t got a direct answer to your question: the figure is super long and it may not be a great PDF to share, but you’ll know best. Here’s what I can suggest: Go to the Github Plots repository and look inside the scr directory for file args.jl

Plenty of goodies to play around with. To identify which does what, you can change its color and increase the linewidth. I can’t see an option to control tick lengths though (but do read on).

const _axis_defaults = KW(
    :guide                       => "",
    :guide_position              => :auto,
    :lims                        => :auto,
    :ticks                       => :auto,
    :scale                       => :identity,
    :rotation                    => 0,
    :flip                        => false,
    :link                        => [],
    :tickfontfamily              => :match,
    :tickfontsize                => 8,
    :tickfonthalign              => :hcenter,
    :tickfontvalign              => :vcenter,
    :tickfontrotation            => 0.0,
    :tickfontcolor               => :match,
    :guidefontfamily             => :match,
    :guidefontsize               => 11,
    :guidefonthalign             => :hcenter,
    :guidefontvalign             => :vcenter,
    :guidefontrotation           => 0.0,
    :guidefontcolor              => :match,
    :foreground_color_axis       => :match,            # axis border/tick colors,
    :foreground_color_border     => :match,            # plot area border/spines,
    :foreground_color_text       => :match,            # tick text color,
    :foreground_color_guide      => :match,            # guide text color,
    :discrete_values             => [],
    :formatter                   => :auto,
    :mirror                      => false,
    :grid                        => true,
    :foreground_color_grid       => :match,            # grid color
    :gridalpha                   => 0.1,
    :gridstyle                   => :solid,
    :gridlinewidth               => 0.5,
    :foreground_color_minor_grid => :match,            # grid color
    :minorgridalpha              => 0.05,
    :minorgridstyle              => :solid,
    :minorgridlinewidth          => 0.5,
    :tick_direction              => :in,
    :minorticks                  => false,
    :minorgrid                   => false,
    :showaxis                    => true,
    :widen                       => true,
    :draw_arrow                  => false,
)

If you look inside axes.jl in the same directory, function axis_drawing_info sets up the axes and the ticks, starting on line 650. It looks like some lengths are hard-coded. You’ll see numbers like 0.012 and 0.006, if you really want it, you could try to change these values and see if it works for you. All the best! :sweat_smile:

Thank you all to your replies. A lot to digest here. I will explore these and get back. Thank you again for the pointers.

For now I decided to go with matplotlib since it did what I wanted much more easily. But thanks for pointers to Plotly. When I have more time, the zooming/panning functionality is more helpful there. Thanks everyone for your suggestions.

1 Like

Actually that was an easier answer, using Plots; pyplot(). At least here it opens an interactive plot which an be zoomed and dragged:

1 Like

Thank you! Will try this out. Really appreciate your help.